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