Home | History | Annotate | Line # | Download | only in sys
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