ptrace_test.c revision 287604
1/*-
2 * Copyright (c) 2015 John Baldwin <jhb@FreeBSD.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27#include <sys/cdefs.h>
28__FBSDID("$FreeBSD: stable/10/tests/sys/kern/ptrace_test.c 287604 2015-09-09 23:39:30Z jhb $");
29
30#include <sys/types.h>
31#include <sys/ptrace.h>
32#include <sys/sysctl.h>
33#include <sys/user.h>
34#include <sys/wait.h>
35#include <errno.h>
36#include <signal.h>
37#include <stdio.h>
38#include <stdlib.h>
39#include <unistd.h>
40#include <atf-c.h>
41
42/*
43 * A variant of ATF_REQUIRE that is suitable for use in child
44 * processes.  This only works if the parent process is tripped up by
45 * the early exit and fails some requirement itself.
46 */
47#define	CHILD_REQUIRE(exp) do {						\
48		if (!(exp))						\
49			child_fail_require(__FILE__, __LINE__,		\
50			    #exp " not met");				\
51	} while (0)
52
53static __dead2 void
54child_fail_require(const char *file, int line, const char *str)
55{
56	char buf[128];
57
58	snprintf(buf, sizeof(buf), "%s:%d: %s\n", file, line, str);
59	write(2, buf, strlen(buf));
60	_exit(32);
61}
62
63static void
64trace_me(void)
65{
66
67	/* Attach the parent process as a tracer of this process. */
68	CHILD_REQUIRE(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
69
70	/* Trigger a stop. */
71	raise(SIGSTOP);
72}
73
74static void
75attach_child(pid_t pid)
76{
77	pid_t wpid;
78	int status;
79
80	ATF_REQUIRE(ptrace(PT_ATTACH, pid, NULL, 0) == 0);
81
82	wpid = waitpid(pid, &status, 0);
83	ATF_REQUIRE(wpid == pid);
84	ATF_REQUIRE(WIFSTOPPED(status));
85	ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP);
86}
87
88static void
89wait_for_zombie(pid_t pid)
90{
91
92	/*
93	 * Wait for a process to exit.  This is kind of gross, but
94	 * there is not a better way.
95	 */
96	for (;;) {
97		struct kinfo_proc kp;
98		size_t len;
99		int mib[4];
100
101		mib[0] = CTL_KERN;
102		mib[1] = KERN_PROC;
103		mib[2] = KERN_PROC_PID;
104		mib[3] = pid;
105		len = sizeof(kp);
106		if (sysctl(mib, nitems(mib), &kp, &len, NULL, 0) == -1) {
107			/* The KERN_PROC_PID sysctl fails for zombies. */
108			ATF_REQUIRE(errno == ESRCH);
109			break;
110		}
111		usleep(5000);
112	}
113}
114
115/*
116 * Verify that a parent debugger process "sees" the exit of a debugged
117 * process exactly once when attached via PT_TRACE_ME.
118 */
119ATF_TC_WITHOUT_HEAD(ptrace__parent_wait_after_trace_me);
120ATF_TC_BODY(ptrace__parent_wait_after_trace_me, tc)
121{
122	pid_t child, wpid;
123	int status;
124
125	ATF_REQUIRE((child = fork()) != -1);
126	if (child == 0) {
127		/* Child process. */
128		trace_me();
129
130		exit(1);
131	}
132
133	/* Parent process. */
134
135	/* The first wait() should report the stop from SIGSTOP. */
136	wpid = waitpid(child, &status, 0);
137	ATF_REQUIRE(wpid == child);
138	ATF_REQUIRE(WIFSTOPPED(status));
139	ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP);
140
141	/* Continue the child ignoring the SIGSTOP. */
142	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (caddr_t)1, 0) != -1);
143
144	/* The second wait() should report the exit status. */
145	wpid = waitpid(child, &status, 0);
146	ATF_REQUIRE(wpid == child);
147	ATF_REQUIRE(WIFEXITED(status));
148	ATF_REQUIRE(WEXITSTATUS(status) == 1);
149
150	/* The child should no longer exist. */
151	wpid = waitpid(child, &status, 0);
152	ATF_REQUIRE(wpid == -1);
153	ATF_REQUIRE(errno == ECHILD);
154}
155
156/*
157 * Verify that a parent debugger process "sees" the exit of a debugged
158 * process exactly once when attached via PT_ATTACH.
159 */
160ATF_TC_WITHOUT_HEAD(ptrace__parent_wait_after_attach);
161ATF_TC_BODY(ptrace__parent_wait_after_attach, tc)
162{
163	pid_t child, wpid;
164	int cpipe[2], status;
165	char c;
166
167	ATF_REQUIRE(pipe(cpipe) == 0);
168	ATF_REQUIRE((child = fork()) != -1);
169	if (child == 0) {
170		/* Child process. */
171		close(cpipe[0]);
172
173		/* Wait for the parent to attach. */
174		CHILD_REQUIRE(read(cpipe[1], &c, sizeof(c)) == 0);
175
176		exit(1);
177	}
178	close(cpipe[1]);
179
180	/* Parent process. */
181
182	/* Attach to the child process. */
183	attach_child(child);
184
185	/* Continue the child ignoring the SIGSTOP. */
186	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (caddr_t)1, 0) != -1);
187
188	/* Signal the child to exit. */
189	close(cpipe[0]);
190
191	/* The second wait() should report the exit status. */
192	wpid = waitpid(child, &status, 0);
193	ATF_REQUIRE(wpid == child);
194	ATF_REQUIRE(WIFEXITED(status));
195	ATF_REQUIRE(WEXITSTATUS(status) == 1);
196
197	/* The child should no longer exist. */
198	wpid = waitpid(child, &status, 0);
199	ATF_REQUIRE(wpid == -1);
200	ATF_REQUIRE(errno == ECHILD);
201}
202
203/*
204 * Verify that a parent process "sees" the exit of a debugged process only
205 * after the debugger has seen it.
206 */
207ATF_TC_WITHOUT_HEAD(ptrace__parent_sees_exit_after_child_debugger);
208ATF_TC_BODY(ptrace__parent_sees_exit_after_child_debugger, tc)
209{
210	pid_t child, debugger, wpid;
211	int cpipe[2], dpipe[2], status;
212	char c;
213
214	ATF_REQUIRE(pipe(cpipe) == 0);
215	ATF_REQUIRE((child = fork()) != -1);
216
217	if (child == 0) {
218		/* Child process. */
219		close(cpipe[0]);
220
221		/* Wait for parent to be ready. */
222		CHILD_REQUIRE(read(cpipe[1], &c, sizeof(c)) == sizeof(c));
223
224		exit(1);
225	}
226	close(cpipe[1]);
227
228	ATF_REQUIRE(pipe(dpipe) == 0);
229	ATF_REQUIRE((debugger = fork()) != -1);
230
231	if (debugger == 0) {
232		/* Debugger process. */
233		close(dpipe[0]);
234
235		CHILD_REQUIRE(ptrace(PT_ATTACH, child, NULL, 0) != -1);
236
237		wpid = waitpid(child, &status, 0);
238		CHILD_REQUIRE(wpid == child);
239		CHILD_REQUIRE(WIFSTOPPED(status));
240		CHILD_REQUIRE(WSTOPSIG(status) == SIGSTOP);
241
242		CHILD_REQUIRE(ptrace(PT_CONTINUE, child, (caddr_t)1, 0) != -1);
243
244		/* Signal parent that debugger is attached. */
245		CHILD_REQUIRE(write(dpipe[1], &c, sizeof(c)) == sizeof(c));
246
247		/* Wait for parent's failed wait. */
248		CHILD_REQUIRE(read(dpipe[1], &c, sizeof(c)) == 0);
249
250		wpid = waitpid(child, &status, 0);
251		CHILD_REQUIRE(wpid == child);
252		CHILD_REQUIRE(WIFEXITED(status));
253		CHILD_REQUIRE(WEXITSTATUS(status) == 1);
254
255		exit(0);
256	}
257	close(dpipe[1]);
258
259	/* Parent process. */
260
261	/* Wait for the debugger to attach to the child. */
262	ATF_REQUIRE(read(dpipe[0], &c, sizeof(c)) == sizeof(c));
263
264	/* Release the child. */
265	ATF_REQUIRE(write(cpipe[0], &c, sizeof(c)) == sizeof(c));
266	ATF_REQUIRE(read(cpipe[0], &c, sizeof(c)) == 0);
267	close(cpipe[0]);
268
269	wait_for_zombie(child);
270
271	/*
272	 * This wait should return a pid of 0 to indicate no status to
273	 * report.  The parent should see the child as non-exited
274	 * until the debugger sees the exit.
275	 */
276	wpid = waitpid(child, &status, WNOHANG);
277	ATF_REQUIRE(wpid == 0);
278
279	/* Signal the debugger to wait for the child. */
280	close(dpipe[0]);
281
282	/* Wait for the debugger. */
283	wpid = waitpid(debugger, &status, 0);
284	ATF_REQUIRE(wpid == debugger);
285	ATF_REQUIRE(WIFEXITED(status));
286	ATF_REQUIRE(WEXITSTATUS(status) == 0);
287
288	/* The child process should now be ready. */
289	wpid = waitpid(child, &status, WNOHANG);
290	ATF_REQUIRE(wpid == child);
291	ATF_REQUIRE(WIFEXITED(status));
292	ATF_REQUIRE(WEXITSTATUS(status) == 1);
293}
294
295/*
296 * Verify that a parent process "sees" the exit of a debugged process
297 * only after a non-direct-child debugger has seen it.  In particular,
298 * various wait() calls in the parent must avoid failing with ESRCH by
299 * checking the parent's orphan list for the debugee.
300 */
301ATF_TC_WITHOUT_HEAD(ptrace__parent_sees_exit_after_unrelated_debugger);
302ATF_TC_BODY(ptrace__parent_sees_exit_after_unrelated_debugger, tc)
303{
304	pid_t child, debugger, fpid, wpid;
305	int cpipe[2], dpipe[2], status;
306	char c;
307
308	ATF_REQUIRE(pipe(cpipe) == 0);
309	ATF_REQUIRE((child = fork()) != -1);
310
311	if (child == 0) {
312		/* Child process. */
313		close(cpipe[0]);
314
315		/* Wait for parent to be ready. */
316		CHILD_REQUIRE(read(cpipe[1], &c, sizeof(c)) == sizeof(c));
317
318		exit(1);
319	}
320	close(cpipe[1]);
321
322	ATF_REQUIRE(pipe(dpipe) == 0);
323	ATF_REQUIRE((debugger = fork()) != -1);
324
325	if (debugger == 0) {
326		/* Debugger parent. */
327
328		/*
329		 * Fork again and drop the debugger parent so that the
330		 * debugger is not a child of the main parent.
331		 */
332		CHILD_REQUIRE((fpid = fork()) != -1);
333		if (fpid != 0)
334			exit(2);
335
336		/* Debugger process. */
337		close(dpipe[0]);
338
339		CHILD_REQUIRE(ptrace(PT_ATTACH, child, NULL, 0) != -1);
340
341		wpid = waitpid(child, &status, 0);
342		CHILD_REQUIRE(wpid == child);
343		CHILD_REQUIRE(WIFSTOPPED(status));
344		CHILD_REQUIRE(WSTOPSIG(status) == SIGSTOP);
345
346		CHILD_REQUIRE(ptrace(PT_CONTINUE, child, (caddr_t)1, 0) != -1);
347
348		/* Signal parent that debugger is attached. */
349		CHILD_REQUIRE(write(dpipe[1], &c, sizeof(c)) == sizeof(c));
350
351		/* Wait for parent's failed wait. */
352		CHILD_REQUIRE(read(dpipe[1], &c, sizeof(c)) == sizeof(c));
353
354		wpid = waitpid(child, &status, 0);
355		CHILD_REQUIRE(wpid == child);
356		CHILD_REQUIRE(WIFEXITED(status));
357		CHILD_REQUIRE(WEXITSTATUS(status) == 1);
358
359		exit(0);
360	}
361	close(dpipe[1]);
362
363	/* Parent process. */
364
365	/* Wait for the debugger parent process to exit. */
366	wpid = waitpid(debugger, &status, 0);
367	ATF_REQUIRE(wpid == debugger);
368	ATF_REQUIRE(WIFEXITED(status));
369	ATF_REQUIRE(WEXITSTATUS(status) == 2);
370
371	/* A WNOHANG wait here should see the non-exited child. */
372	wpid = waitpid(child, &status, WNOHANG);
373	ATF_REQUIRE(wpid == 0);
374
375	/* Wait for the debugger to attach to the child. */
376	ATF_REQUIRE(read(dpipe[0], &c, sizeof(c)) == sizeof(c));
377
378	/* Release the child. */
379	ATF_REQUIRE(write(cpipe[0], &c, sizeof(c)) == sizeof(c));
380	ATF_REQUIRE(read(cpipe[0], &c, sizeof(c)) == 0);
381	close(cpipe[0]);
382
383	wait_for_zombie(child);
384
385	/*
386	 * This wait should return a pid of 0 to indicate no status to
387	 * report.  The parent should see the child as non-exited
388	 * until the debugger sees the exit.
389	 */
390	wpid = waitpid(child, &status, WNOHANG);
391	ATF_REQUIRE(wpid == 0);
392
393	/* Signal the debugger to wait for the child. */
394	ATF_REQUIRE(write(dpipe[0], &c, sizeof(c)) == sizeof(c));
395
396	/* Wait for the debugger. */
397	ATF_REQUIRE(read(dpipe[0], &c, sizeof(c)) == 0);
398	close(dpipe[0]);
399
400	/* The child process should now be ready. */
401	wpid = waitpid(child, &status, WNOHANG);
402	ATF_REQUIRE(wpid == child);
403	ATF_REQUIRE(WIFEXITED(status));
404	ATF_REQUIRE(WEXITSTATUS(status) == 1);
405}
406
407/*
408 * The parent process should always act the same regardless of how the
409 * debugger is attached to it.
410 */
411static __dead2 void
412follow_fork_parent(void)
413{
414	pid_t fpid, wpid;
415	int status;
416
417	CHILD_REQUIRE((fpid = fork()) != -1);
418
419	if (fpid == 0)
420		/* Child */
421		exit(2);
422
423	wpid = waitpid(fpid, &status, 0);
424	CHILD_REQUIRE(wpid == fpid);
425	CHILD_REQUIRE(WIFEXITED(status));
426	CHILD_REQUIRE(WEXITSTATUS(status) == 2);
427
428	exit(1);
429}
430
431/*
432 * Helper routine for follow fork tests.  This waits for two stops
433 * that report both "sides" of a fork.  It returns the pid of the new
434 * child process.
435 */
436static pid_t
437handle_fork_events(pid_t parent)
438{
439	struct ptrace_lwpinfo pl;
440	bool fork_reported[2];
441	pid_t child, wpid;
442	int i, status;
443
444	fork_reported[0] = false;
445	fork_reported[1] = false;
446	child = -1;
447
448	/*
449	 * Each process should report a fork event.  The parent should
450	 * report a PL_FLAG_FORKED event, and the child should report
451	 * a PL_FLAG_CHILD event.
452	 */
453	for (i = 0; i < 2; i++) {
454		wpid = wait(&status);
455		ATF_REQUIRE(wpid > 0);
456		ATF_REQUIRE(WIFSTOPPED(status));
457
458		ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl,
459		    sizeof(pl)) != -1);
460		ATF_REQUIRE((pl.pl_flags & (PL_FLAG_FORKED | PL_FLAG_CHILD)) !=
461		    0);
462		ATF_REQUIRE((pl.pl_flags & (PL_FLAG_FORKED | PL_FLAG_CHILD)) !=
463		    (PL_FLAG_FORKED | PL_FLAG_CHILD));
464		if (pl.pl_flags & PL_FLAG_CHILD) {
465			ATF_REQUIRE(wpid != parent);
466			ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP);
467			ATF_REQUIRE(!fork_reported[1]);
468			if (child == -1)
469				child = wpid;
470			else
471				ATF_REQUIRE(child == wpid);
472			fork_reported[1] = true;
473		} else {
474			ATF_REQUIRE(wpid == parent);
475			ATF_REQUIRE(WSTOPSIG(status) == SIGTRAP);
476			ATF_REQUIRE(!fork_reported[0]);
477			if (child == -1)
478				child = pl.pl_child_pid;
479			else
480				ATF_REQUIRE(child == pl.pl_child_pid);
481			fork_reported[0] = true;
482		}
483	}
484
485	return (child);
486}
487
488/*
489 * Verify that a new child process is stopped after a followed fork and
490 * that the traced parent sees the exit of the child after the debugger
491 * when both processes remain attached to the debugger.
492 */
493ATF_TC_WITHOUT_HEAD(ptrace__follow_fork_both_attached);
494ATF_TC_BODY(ptrace__follow_fork_both_attached, tc)
495{
496	pid_t children[0], fpid, wpid;
497	int status;
498
499	ATF_REQUIRE((fpid = fork()) != -1);
500	if (fpid == 0) {
501		trace_me();
502		follow_fork_parent();
503	}
504
505	/* Parent process. */
506	children[0] = fpid;
507
508	/* The first wait() should report the stop from SIGSTOP. */
509	wpid = waitpid(children[0], &status, 0);
510	ATF_REQUIRE(wpid == children[0]);
511	ATF_REQUIRE(WIFSTOPPED(status));
512	ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP);
513
514	ATF_REQUIRE(ptrace(PT_FOLLOW_FORK, children[0], NULL, 1) != -1);
515
516	/* Continue the child ignoring the SIGSTOP. */
517	ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1);
518
519	children[1] = handle_fork_events(children[0]);
520	ATF_REQUIRE(children[1] > 0);
521
522	ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1);
523	ATF_REQUIRE(ptrace(PT_CONTINUE, children[1], (caddr_t)1, 0) != -1);
524
525	/*
526	 * The child can't exit until the grandchild reports status, so the
527	 * grandchild should report its exit first to the debugger.
528	 */
529	wpid = wait(&status);
530	ATF_REQUIRE(wpid == children[1]);
531	ATF_REQUIRE(WIFEXITED(status));
532	ATF_REQUIRE(WEXITSTATUS(status) == 2);
533
534	wpid = wait(&status);
535	ATF_REQUIRE(wpid == children[0]);
536	ATF_REQUIRE(WIFEXITED(status));
537	ATF_REQUIRE(WEXITSTATUS(status) == 1);
538
539	wpid = wait(&status);
540	ATF_REQUIRE(wpid == -1);
541	ATF_REQUIRE(errno == ECHILD);
542}
543
544/*
545 * Verify that a new child process is stopped after a followed fork
546 * and that the traced parent sees the exit of the child when the new
547 * child process is detached after it reports its fork.
548 */
549ATF_TC_WITHOUT_HEAD(ptrace__follow_fork_child_detached);
550ATF_TC_BODY(ptrace__follow_fork_child_detached, tc)
551{
552	pid_t children[0], fpid, wpid;
553	int status;
554
555	ATF_REQUIRE((fpid = fork()) != -1);
556	if (fpid == 0) {
557		trace_me();
558		follow_fork_parent();
559	}
560
561	/* Parent process. */
562	children[0] = fpid;
563
564	/* The first wait() should report the stop from SIGSTOP. */
565	wpid = waitpid(children[0], &status, 0);
566	ATF_REQUIRE(wpid == children[0]);
567	ATF_REQUIRE(WIFSTOPPED(status));
568	ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP);
569
570	ATF_REQUIRE(ptrace(PT_FOLLOW_FORK, children[0], NULL, 1) != -1);
571
572	/* Continue the child ignoring the SIGSTOP. */
573	ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1);
574
575	children[1] = handle_fork_events(children[0]);
576	ATF_REQUIRE(children[1] > 0);
577
578	ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1);
579	ATF_REQUIRE(ptrace(PT_DETACH, children[1], (caddr_t)1, 0) != -1);
580
581	/*
582	 * Should not see any status from the grandchild now, only the
583	 * child.
584	 */
585	wpid = wait(&status);
586	ATF_REQUIRE(wpid == children[0]);
587	ATF_REQUIRE(WIFEXITED(status));
588	ATF_REQUIRE(WEXITSTATUS(status) == 1);
589
590	wpid = wait(&status);
591	ATF_REQUIRE(wpid == -1);
592	ATF_REQUIRE(errno == ECHILD);
593}
594
595/*
596 * Verify that a new child process is stopped after a followed fork
597 * and that the traced parent sees the exit of the child when the
598 * traced parent is detached after the fork.
599 */
600ATF_TC_WITHOUT_HEAD(ptrace__follow_fork_parent_detached);
601ATF_TC_BODY(ptrace__follow_fork_parent_detached, tc)
602{
603	pid_t children[0], fpid, wpid;
604	int status;
605
606	ATF_REQUIRE((fpid = fork()) != -1);
607	if (fpid == 0) {
608		trace_me();
609		follow_fork_parent();
610	}
611
612	/* Parent process. */
613	children[0] = fpid;
614
615	/* The first wait() should report the stop from SIGSTOP. */
616	wpid = waitpid(children[0], &status, 0);
617	ATF_REQUIRE(wpid == children[0]);
618	ATF_REQUIRE(WIFSTOPPED(status));
619	ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP);
620
621	ATF_REQUIRE(ptrace(PT_FOLLOW_FORK, children[0], NULL, 1) != -1);
622
623	/* Continue the child ignoring the SIGSTOP. */
624	ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1);
625
626	children[1] = handle_fork_events(children[0]);
627	ATF_REQUIRE(children[1] > 0);
628
629	ATF_REQUIRE(ptrace(PT_DETACH, children[0], (caddr_t)1, 0) != -1);
630	ATF_REQUIRE(ptrace(PT_CONTINUE, children[1], (caddr_t)1, 0) != -1);
631
632	/*
633	 * The child can't exit until the grandchild reports status, so the
634	 * grandchild should report its exit first to the debugger.
635	 *
636	 * Even though the child process is detached, it is still a
637	 * child of the debugger, so it will still report it's exit
638	 * after the grandchild.
639	 */
640	wpid = wait(&status);
641	ATF_REQUIRE(wpid == children[1]);
642	ATF_REQUIRE(WIFEXITED(status));
643	ATF_REQUIRE(WEXITSTATUS(status) == 2);
644
645	wpid = wait(&status);
646	ATF_REQUIRE(wpid == children[0]);
647	ATF_REQUIRE(WIFEXITED(status));
648	ATF_REQUIRE(WEXITSTATUS(status) == 1);
649
650	wpid = wait(&status);
651	ATF_REQUIRE(wpid == -1);
652	ATF_REQUIRE(errno == ECHILD);
653}
654
655static void
656attach_fork_parent(int cpipe[2])
657{
658	pid_t fpid;
659
660	close(cpipe[0]);
661
662	/* Double-fork to disassociate from the debugger. */
663	CHILD_REQUIRE((fpid = fork()) != -1);
664	if (fpid != 0)
665		exit(3);
666
667	/* Send the pid of the disassociated child to the debugger. */
668	fpid = getpid();
669	CHILD_REQUIRE(write(cpipe[1], &fpid, sizeof(fpid)) == sizeof(fpid));
670
671	/* Wait for the debugger to attach. */
672	CHILD_REQUIRE(read(cpipe[1], &fpid, sizeof(fpid)) == 0);
673}
674
675/*
676 * Verify that a new child process is stopped after a followed fork and
677 * that the traced parent sees the exit of the child after the debugger
678 * when both processes remain attached to the debugger.  In this test
679 * the parent that forks is not a direct child of the debugger.
680 */
681ATF_TC_WITHOUT_HEAD(ptrace__follow_fork_both_attached_unrelated_debugger);
682ATF_TC_BODY(ptrace__follow_fork_both_attached_unrelated_debugger, tc)
683{
684	pid_t children[0], fpid, wpid;
685	int cpipe[2], status;
686
687	ATF_REQUIRE(pipe(cpipe) == 0);
688	ATF_REQUIRE((fpid = fork()) != -1);
689	if (fpid == 0) {
690		attach_fork_parent(cpipe);
691		follow_fork_parent();
692	}
693
694	/* Parent process. */
695	close(cpipe[1]);
696
697	/* Wait for the direct child to exit. */
698	wpid = waitpid(fpid, &status, 0);
699	ATF_REQUIRE(wpid == fpid);
700	ATF_REQUIRE(WIFEXITED(status));
701	ATF_REQUIRE(WEXITSTATUS(status) == 3);
702
703	/* Read the pid of the fork parent. */
704	ATF_REQUIRE(read(cpipe[0], &children[0], sizeof(children[0])) ==
705	    sizeof(children[0]));
706
707	/* Attach to the fork parent. */
708	attach_child(children[0]);
709
710	ATF_REQUIRE(ptrace(PT_FOLLOW_FORK, children[0], NULL, 1) != -1);
711
712	/* Continue the fork parent ignoring the SIGSTOP. */
713	ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1);
714
715	/* Signal the fork parent to continue. */
716	close(cpipe[0]);
717
718	children[1] = handle_fork_events(children[0]);
719	ATF_REQUIRE(children[1] > 0);
720
721	ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1);
722	ATF_REQUIRE(ptrace(PT_CONTINUE, children[1], (caddr_t)1, 0) != -1);
723
724	/*
725	 * The fork parent can't exit until the child reports status,
726	 * so the child should report its exit first to the debugger.
727	 */
728	wpid = wait(&status);
729	ATF_REQUIRE(wpid == children[1]);
730	ATF_REQUIRE(WIFEXITED(status));
731	ATF_REQUIRE(WEXITSTATUS(status) == 2);
732
733	wpid = wait(&status);
734	ATF_REQUIRE(wpid == children[0]);
735	ATF_REQUIRE(WIFEXITED(status));
736	ATF_REQUIRE(WEXITSTATUS(status) == 1);
737
738	wpid = wait(&status);
739	ATF_REQUIRE(wpid == -1);
740	ATF_REQUIRE(errno == ECHILD);
741}
742
743/*
744 * Verify that a new child process is stopped after a followed fork
745 * and that the traced parent sees the exit of the child when the new
746 * child process is detached after it reports its fork.  In this test
747 * the parent that forks is not a direct child of the debugger.
748 */
749ATF_TC_WITHOUT_HEAD(ptrace__follow_fork_child_detached_unrelated_debugger);
750ATF_TC_BODY(ptrace__follow_fork_child_detached_unrelated_debugger, tc)
751{
752	pid_t children[0], fpid, wpid;
753	int cpipe[2], status;
754
755	ATF_REQUIRE(pipe(cpipe) == 0);
756	ATF_REQUIRE((fpid = fork()) != -1);
757	if (fpid == 0) {
758		attach_fork_parent(cpipe);
759		follow_fork_parent();
760	}
761
762	/* Parent process. */
763	close(cpipe[1]);
764
765	/* Wait for the direct child to exit. */
766	wpid = waitpid(fpid, &status, 0);
767	ATF_REQUIRE(wpid == fpid);
768	ATF_REQUIRE(WIFEXITED(status));
769	ATF_REQUIRE(WEXITSTATUS(status) == 3);
770
771	/* Read the pid of the fork parent. */
772	ATF_REQUIRE(read(cpipe[0], &children[0], sizeof(children[0])) ==
773	    sizeof(children[0]));
774
775	/* Attach to the fork parent. */
776	attach_child(children[0]);
777
778	ATF_REQUIRE(ptrace(PT_FOLLOW_FORK, children[0], NULL, 1) != -1);
779
780	/* Continue the fork parent ignoring the SIGSTOP. */
781	ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1);
782
783	/* Signal the fork parent to continue. */
784	close(cpipe[0]);
785
786	children[1] = handle_fork_events(children[0]);
787	ATF_REQUIRE(children[1] > 0);
788
789	ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1);
790	ATF_REQUIRE(ptrace(PT_DETACH, children[1], (caddr_t)1, 0) != -1);
791
792	/*
793	 * Should not see any status from the child now, only the fork
794	 * parent.
795	 */
796	wpid = wait(&status);
797	ATF_REQUIRE(wpid == children[0]);
798	ATF_REQUIRE(WIFEXITED(status));
799	ATF_REQUIRE(WEXITSTATUS(status) == 1);
800
801	wpid = wait(&status);
802	ATF_REQUIRE(wpid == -1);
803	ATF_REQUIRE(errno == ECHILD);
804}
805
806/*
807 * Verify that a new child process is stopped after a followed fork
808 * and that the traced parent sees the exit of the child when the
809 * traced parent is detached after the fork.  In this test the parent
810 * that forks is not a direct child of the debugger.
811 */
812ATF_TC_WITHOUT_HEAD(ptrace__follow_fork_parent_detached_unrelated_debugger);
813ATF_TC_BODY(ptrace__follow_fork_parent_detached_unrelated_debugger, tc)
814{
815	pid_t children[0], fpid, wpid;
816	int cpipe[2], status;
817
818	ATF_REQUIRE(pipe(cpipe) == 0);
819	ATF_REQUIRE((fpid = fork()) != -1);
820	if (fpid == 0) {
821		attach_fork_parent(cpipe);
822		follow_fork_parent();
823	}
824
825	/* Parent process. */
826	close(cpipe[1]);
827
828	/* Wait for the direct child to exit. */
829	wpid = waitpid(fpid, &status, 0);
830	ATF_REQUIRE(wpid == fpid);
831	ATF_REQUIRE(WIFEXITED(status));
832	ATF_REQUIRE(WEXITSTATUS(status) == 3);
833
834	/* Read the pid of the fork parent. */
835	ATF_REQUIRE(read(cpipe[0], &children[0], sizeof(children[0])) ==
836	    sizeof(children[0]));
837
838	/* Attach to the fork parent. */
839	attach_child(children[0]);
840
841	ATF_REQUIRE(ptrace(PT_FOLLOW_FORK, children[0], NULL, 1) != -1);
842
843	/* Continue the fork parent ignoring the SIGSTOP. */
844	ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1);
845
846	/* Signal the fork parent to continue. */
847	close(cpipe[0]);
848
849	children[1] = handle_fork_events(children[0]);
850	ATF_REQUIRE(children[1] > 0);
851
852	ATF_REQUIRE(ptrace(PT_DETACH, children[0], (caddr_t)1, 0) != -1);
853	ATF_REQUIRE(ptrace(PT_CONTINUE, children[1], (caddr_t)1, 0) != -1);
854
855	/*
856	 * Should not see any status from the fork parent now, only
857	 * the child.
858	 */
859	wpid = wait(&status);
860	ATF_REQUIRE(wpid == children[1]);
861	ATF_REQUIRE(WIFEXITED(status));
862	ATF_REQUIRE(WEXITSTATUS(status) == 2);
863
864	wpid = wait(&status);
865	ATF_REQUIRE(wpid == -1);
866	ATF_REQUIRE(errno == ECHILD);
867}
868
869ATF_TP_ADD_TCS(tp)
870{
871
872	ATF_TP_ADD_TC(tp, ptrace__parent_wait_after_trace_me);
873	ATF_TP_ADD_TC(tp, ptrace__parent_wait_after_attach);
874	ATF_TP_ADD_TC(tp, ptrace__parent_sees_exit_after_child_debugger);
875	ATF_TP_ADD_TC(tp, ptrace__parent_sees_exit_after_unrelated_debugger);
876	ATF_TP_ADD_TC(tp, ptrace__follow_fork_both_attached);
877	ATF_TP_ADD_TC(tp, ptrace__follow_fork_child_detached);
878	ATF_TP_ADD_TC(tp, ptrace__follow_fork_parent_detached);
879	ATF_TP_ADD_TC(tp, ptrace__follow_fork_both_attached_unrelated_debugger);
880	ATF_TP_ADD_TC(tp,
881	    ptrace__follow_fork_child_detached_unrelated_debugger);
882	ATF_TP_ADD_TC(tp,
883	    ptrace__follow_fork_parent_detached_unrelated_debugger);
884
885	return (atf_no_error());
886}
887