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