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