1 /* $NetBSD: t_ptrace_clone_wait.h,v 1.3 2020/05/11 21:18:11 kamil Exp $ */
2
3 /*-
4 * Copyright (c) 2016, 2017, 2018, 2019, 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
clone_body(int flags,bool trackfork,bool trackvfork,bool trackvforkdone)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
CLONE_TEST(clone_vm1,CLONE_VM,false,false,false)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 kp_sigmask = kp.p_sigmask;
418 kp_sigignore = kp.p_sigignore;
419
420 DPRINTF("Set PTRACE_FORK | PTRACE_VFORK | PTRACE_VFORK_DONE in "
421 "EVENT_MASK for the child %d\n", child);
422 event.pe_set_event = PTRACE_FORK | PTRACE_VFORK | PTRACE_VFORK_DONE;
423 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
424
425 DPRINTF("Before resuming the child process where it left off and "
426 "without signal to be sent\n");
427 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
428
429 DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME,
430 child);
431 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
432 child);
433
434 validate_status_stopped(status, SIGTRAP);
435
436 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
437
438 if (masked) {
439 DPRINTF("kp_sigmask="
440 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
441 PRIx32 "\n",
442 kp_sigmask.__bits[0], kp_sigmask.__bits[1],
443 kp_sigmask.__bits[2], kp_sigmask.__bits[3]);
444
445 DPRINTF("kp.p_sigmask="
446 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
447 PRIx32 "\n",
448 kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1],
449 kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]);
450
451 ATF_REQUIRE(sigismember((sigset_t *)&kp.p_sigmask,
452 SIGTRAP));
453 }
454
455 if (ignored) {
456 DPRINTF("kp_sigignore="
457 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
458 PRIx32 "\n",
459 kp_sigignore.__bits[0], kp_sigignore.__bits[1],
460 kp_sigignore.__bits[2], kp_sigignore.__bits[3]);
461
462 DPRINTF("kp.p_sigignore="
463 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
464 PRIx32 "\n",
465 kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1],
466 kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]);
467
468 ATF_REQUIRE(sigismember((sigset_t *)&kp.p_sigignore,
469 SIGTRAP));
470 }
471
472 SYSCALL_REQUIRE(
473 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
474 DPRINTF("state.pe_report_event=%#x pid=%d\n", state.pe_report_event,
475 child2);
476 if (!(flags & CLONE_VFORK)) {
477 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK,
478 PTRACE_FORK);
479 } else {
480 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK,
481 PTRACE_VFORK);
482 }
483
484 child2 = state.pe_other_pid;
485 DPRINTF("Reported ptrace event with forkee %d\n", child2);
486
487 DPRINTF("Before calling %s() for the forkee %d of the child "
488 "%d\n", TWAIT_FNAME, child2, child);
489 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
490 child2);
491
492 validate_status_stopped(status, SIGTRAP);
493
494 name[3] = child2;
495 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
496
497 if (masked) {
498 DPRINTF("kp_sigmask="
499 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
500 PRIx32 "\n",
501 kp_sigmask.__bits[0], kp_sigmask.__bits[1],
502 kp_sigmask.__bits[2], kp_sigmask.__bits[3]);
503
504 DPRINTF("kp.p_sigmask="
505 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
506 PRIx32 "\n",
507 kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1],
508 kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]);
509
510 ATF_REQUIRE(sigismember((sigset_t *)&kp.p_sigmask,
511 SIGTRAP));
512 }
513
514 if (ignored) {
515 DPRINTF("kp_sigignore="
516 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
517 PRIx32 "\n",
518 kp_sigignore.__bits[0], kp_sigignore.__bits[1],
519 kp_sigignore.__bits[2], kp_sigignore.__bits[3]);
520
521 DPRINTF("kp.p_sigignore="
522 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
523 PRIx32 "\n",
524 kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1],
525 kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]);
526
527 ATF_REQUIRE(sigismember((sigset_t *)&kp.p_sigignore,
528 SIGTRAP));
529 }
530
531 SYSCALL_REQUIRE(
532 ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
533 if (!(flags & CLONE_VFORK)) {
534 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK,
535 PTRACE_FORK);
536 } else {
537 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK,
538 PTRACE_VFORK);
539 }
540
541 ATF_REQUIRE_EQ(state.pe_other_pid, child);
542
543 DPRINTF("Before resuming the forkee process where it left off "
544 "and without signal to be sent\n");
545 SYSCALL_REQUIRE(
546 ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
547
548 DPRINTF("Before resuming the child process where it left off "
549 "and without signal to be sent\n");
550 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
551
552 if (flags & CLONE_VFORK) {
553 DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME,
554 child);
555 TWAIT_REQUIRE_SUCCESS(
556 wpid = TWAIT_GENERIC(child, &status, 0), child);
557
558 validate_status_stopped(status, SIGTRAP);
559
560 name[3] = child;
561 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
562
563 /*
564 * SIGCHLD is now pending in the signal queue and
565 * the kernel presents it to userland as a masked signal.
566 */
567 sigdelset((sigset_t *)&kp.p_sigmask, SIGCHLD);
568
569 if (masked) {
570 DPRINTF("kp_sigmask="
571 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
572 PRIx32 "\n",
573 kp_sigmask.__bits[0], kp_sigmask.__bits[1],
574 kp_sigmask.__bits[2], kp_sigmask.__bits[3]);
575
576 DPRINTF("kp.p_sigmask="
577 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
578 PRIx32 "\n",
579 kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1],
580 kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]);
581
582 ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask,
583 sizeof(kp_sigmask)));
584 }
585
586 if (ignored) {
587 DPRINTF("kp_sigignore="
588 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
589 PRIx32 "\n",
590 kp_sigignore.__bits[0], kp_sigignore.__bits[1],
591 kp_sigignore.__bits[2], kp_sigignore.__bits[3]);
592
593 DPRINTF("kp.p_sigignore="
594 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
595 PRIx32 "\n",
596 kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1],
597 kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]);
598
599 ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore,
600 sizeof(kp_sigignore)));
601 }
602
603 SYSCALL_REQUIRE(
604 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
605 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE);
606
607 child2 = state.pe_other_pid;
608 DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n",
609 child2);
610
611 DPRINTF("Before resuming the child process where it left off "
612 "and without signal to be sent\n");
613 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
614 }
615
616 DPRINTF("Before calling %s() for the forkee - expected exited"
617 "\n", TWAIT_FNAME);
618 TWAIT_REQUIRE_SUCCESS(
619 wpid = TWAIT_GENERIC(child2, &status, 0), child2);
620
621 validate_status_exited(status, exitval2);
622
623 DPRINTF("Before calling %s() for the forkee - expected no "
624 "process\n", TWAIT_FNAME);
625 TWAIT_REQUIRE_FAILURE(ECHILD,
626 wpid = TWAIT_GENERIC(child2, &status, 0));
627
628 DPRINTF("Before calling %s() for the child - expected stopped "
629 "SIGCHLD\n", TWAIT_FNAME);
630 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
631
632 validate_status_stopped(status, SIGCHLD);
633
634 DPRINTF("Before resuming the child process where it left off and "
635 "without signal to be sent\n");
636 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
637
638 DPRINTF("Before calling %s() for the child - expected exited\n",
639 TWAIT_FNAME);
640 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
641
642 validate_status_exited(status, exitval);
643
644 DPRINTF("Before calling %s() for the child - expected no process\n",
645 TWAIT_FNAME);
646 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
647 }
648
649 #define CLONE_TEST2(name,flags,masked,ignored) \
650 ATF_TC(name); \
651 ATF_TC_HEAD(name, tc) \
652 { \
653 atf_tc_set_md_var(tc, "descr", "Verify that clone(%s) is caught"\
654 " regardless of signal %s%s", \
655 #flags, masked ? "masked" : "", ignored ? "ignored" : ""); \
656 } \
657 \
658 ATF_TC_BODY(name, tc) \
659 { \
660 \
661 clone_body2(flags, masked, ignored); \
662 }
663
664 CLONE_TEST2(clone_signalignored, 0, true, false)
665 CLONE_TEST2(clone_signalmasked, 0, false, true)
CLONE_TEST2(clone_vm_signalignored,CLONE_VM,true,false)666 CLONE_TEST2(clone_vm_signalignored, CLONE_VM, true, false)
667 CLONE_TEST2(clone_vm_signalmasked, CLONE_VM, false, true)
668 CLONE_TEST2(clone_fs_signalignored, CLONE_FS, true, false)
669 CLONE_TEST2(clone_fs_signalmasked, CLONE_FS, false, true)
670 CLONE_TEST2(clone_files_signalignored, CLONE_FILES, true, false)
671 CLONE_TEST2(clone_files_signalmasked, CLONE_FILES, false, true)
672 //CLONE_TEST2(clone_sighand_signalignored, CLONE_SIGHAND, true, false) // XXX
673 //CLONE_TEST2(clone_sighand_signalmasked, CLONE_SIGHAND, false, true) // XXX
674 CLONE_TEST2(clone_vfork_signalignored, CLONE_VFORK, true, false)
675 CLONE_TEST2(clone_vfork_signalmasked, CLONE_VFORK, false, true)
676 #endif
677
678 /// ----------------------------------------------------------------------------
679
680 #if defined(TWAIT_HAVE_PID)
681 static void
682 traceme_vfork_clone_body(int flags)
683 {
684 const int exitval = 5;
685 const int exitval2 = 15;
686 pid_t child, child2 = 0, wpid;
687 #if defined(TWAIT_HAVE_STATUS)
688 int status;
689 #endif
690
691 const size_t stack_size = 1024 * 1024;
692 void *stack, *stack_base;
693
694 stack = malloc(stack_size);
695 ATF_REQUIRE(stack != NULL);
696
697 #ifdef __MACHINE_STACK_GROWS_UP
698 stack_base = stack;
699 #else
700 stack_base = (char *)stack + stack_size;
701 #endif
702
703 SYSCALL_REQUIRE((child = vfork()) != -1);
704 if (child == 0) {
705 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
706 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
707
708 DPRINTF("Before forking process PID=%d flags=%#x\n", getpid(),
709 flags);
710 SYSCALL_REQUIRE((child2 = __clone(clone_func, stack_base,
711 flags|SIGCHLD, (void *)(intptr_t)exitval2)) != -1);
712
713 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(),
714 child2);
715
716 // XXX WALLSIG?
717 FORKEE_REQUIRE_SUCCESS
718 (wpid = TWAIT_GENERIC(child2, &status, WALLSIG), child2);
719
720 forkee_status_exited(status, exitval2);
721
722 DPRINTF("Before exiting of the child process\n");
723 _exit(exitval);
724 }
725 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
726
727 DPRINTF("Before calling %s() for the child - expected exited\n",
728 TWAIT_FNAME);
729 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
730
731 validate_status_exited(status, exitval);
732
733 DPRINTF("Before calling %s() for the child - expected no process\n",
734 TWAIT_FNAME);
735 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
736 }
737
738 #define TRACEME_VFORK_CLONE_TEST(name,flags) \
739 ATF_TC(name); \
740 ATF_TC_HEAD(name, tc) \
741 { \
742 atf_tc_set_md_var(tc, "descr", "Verify that clone(%s) is " \
743 "handled correctly with vfork(2)ed tracer", \
744 #flags); \
745 } \
746 \
747 ATF_TC_BODY(name, tc) \
748 { \
749 \
750 traceme_vfork_clone_body(flags); \
751 }
752
753 TRACEME_VFORK_CLONE_TEST(traceme_vfork_clone, 0)
754 TRACEME_VFORK_CLONE_TEST(traceme_vfork_clone_vm, CLONE_VM)
755 TRACEME_VFORK_CLONE_TEST(traceme_vfork_clone_fs, CLONE_FS)
756 TRACEME_VFORK_CLONE_TEST(traceme_vfork_clone_files, CLONE_FILES)
757 //TRACEME_VFORK_CLONE_TEST(traceme_vfork_clone_sighand, CLONE_SIGHAND) // XXX
758 TRACEME_VFORK_CLONE_TEST(traceme_vfork_clone_vfork, CLONE_VFORK)
759 #endif
760
761 #define ATF_TP_ADD_TCS_PTRACE_WAIT_CLONE() \
762 ATF_TP_ADD_TC(tp, clone1); \
763 ATF_TP_ADD_TC_HAVE_PID(tp, clone2); \
764 ATF_TP_ADD_TC_HAVE_PID(tp, clone3); \
765 ATF_TP_ADD_TC_HAVE_PID(tp, clone4); \
766 ATF_TP_ADD_TC(tp, clone5); \
767 ATF_TP_ADD_TC_HAVE_PID(tp, clone6); \
768 ATF_TP_ADD_TC_HAVE_PID(tp, clone7); \
769 ATF_TP_ADD_TC_HAVE_PID(tp, clone8); \
770 ATF_TP_ADD_TC(tp, clone_vm1); \
771 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm2); \
772 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm3); \
773 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm4); \
774 ATF_TP_ADD_TC(tp, clone_vm5); \
775 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm6); \
776 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm7); \
777 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm8); \
778 ATF_TP_ADD_TC(tp, clone_fs1); \
779 ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs2); \
780 ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs3); \
781 ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs4); \
782 ATF_TP_ADD_TC(tp, clone_fs5); \
783 ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs6); \
784 ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs7); \
785 ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs8); \
786 ATF_TP_ADD_TC(tp, clone_files1); \
787 ATF_TP_ADD_TC_HAVE_PID(tp, clone_files2); \
788 ATF_TP_ADD_TC_HAVE_PID(tp, clone_files3); \
789 ATF_TP_ADD_TC_HAVE_PID(tp, clone_files4); \
790 ATF_TP_ADD_TC(tp, clone_files5); \
791 ATF_TP_ADD_TC_HAVE_PID(tp, clone_files6); \
792 ATF_TP_ADD_TC_HAVE_PID(tp, clone_files7); \
793 ATF_TP_ADD_TC_HAVE_PID(tp, clone_files8); \
794 ATF_TP_ADD_TC(tp, clone_vfork1); \
795 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork2); \
796 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork3); \
797 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork4); \
798 ATF_TP_ADD_TC(tp, clone_vfork5); \
799 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork6); \
800 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork7); \
801 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork8); \
802 ATF_TP_ADD_TC_HAVE_PID(tp, clone_signalignored); \
803 ATF_TP_ADD_TC_HAVE_PID(tp, clone_signalmasked); \
804 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm_signalignored); \
805 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm_signalmasked); \
806 ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs_signalignored); \
807 ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs_signalmasked); \
808 ATF_TP_ADD_TC_HAVE_PID(tp, clone_files_signalignored); \
809 ATF_TP_ADD_TC_HAVE_PID(tp, clone_files_signalmasked); \
810 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork_signalignored); \
811 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork_signalmasked); \
812 ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone); \
813 ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone_vm); \
814 ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone_fs); \
815 ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone_files); \
816 ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone_vfork);
817
818 // ATF_TP_ADD_TC(tp, clone_sighand1); // XXX
819 // ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand2); // XXX
820 // ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand3); // XXX
821 // ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand4); // XXX
822 // ATF_TP_ADD_TC(tp, clone_sighand5); // XXX
823 // ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand6); // XXX
824 // ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand7); // XXX
825 // ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand8); // XXX
826
827 // ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand_signalignored); // XXX
828 // ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand_signalmasked); // XXX
829
830 // ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone_sighand); // XXX
831