1*7f74343bSsimonb /* $NetBSD: t_ptrace_signal_wait.h,v 1.5 2021/03/19 00:44:09 simonb Exp $ */
2a0f774c8Skamil
3a0f774c8Skamil /*-
4a0f774c8Skamil * Copyright (c) 2016, 2017, 2018, 2019, 2020 The NetBSD Foundation, Inc.
5a0f774c8Skamil * All rights reserved.
6a0f774c8Skamil *
7a0f774c8Skamil * Redistribution and use in source and binary forms, with or without
8a0f774c8Skamil * modification, are permitted provided that the following conditions
9a0f774c8Skamil * are met:
10a0f774c8Skamil * 1. Redistributions of source code must retain the above copyright
11a0f774c8Skamil * notice, this list of conditions and the following disclaimer.
12a0f774c8Skamil * 2. Redistributions in binary form must reproduce the above copyright
13a0f774c8Skamil * notice, this list of conditions and the following disclaimer in the
14a0f774c8Skamil * documentation and/or other materials provided with the distribution.
15a0f774c8Skamil *
16a0f774c8Skamil * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17a0f774c8Skamil * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18a0f774c8Skamil * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19a0f774c8Skamil * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20a0f774c8Skamil * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21a0f774c8Skamil * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22a0f774c8Skamil * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23a0f774c8Skamil * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24a0f774c8Skamil * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25a0f774c8Skamil * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26a0f774c8Skamil * POSSIBILITY OF SUCH DAMAGE.
27a0f774c8Skamil */
28a0f774c8Skamil
29a0f774c8Skamil
30a0f774c8Skamil static void
traceme_raise(int sigval)31a0f774c8Skamil traceme_raise(int sigval)
32a0f774c8Skamil {
33a0f774c8Skamil const int exitval = 5;
34a0f774c8Skamil pid_t child, wpid;
35a0f774c8Skamil #if defined(TWAIT_HAVE_STATUS)
36a0f774c8Skamil int status;
37a0f774c8Skamil #endif
38a0f774c8Skamil
39a0f774c8Skamil ptrace_state_t state, zero_state;
40a0f774c8Skamil const int slen = sizeof(state);
41a0f774c8Skamil struct ptrace_siginfo info;
42a0f774c8Skamil memset(&zero_state, 0, sizeof(zero_state));
43a0f774c8Skamil memset(&info, 0, sizeof(info));
44a0f774c8Skamil
45a0f774c8Skamil DPRINTF("Before forking process PID=%d\n", getpid());
46a0f774c8Skamil SYSCALL_REQUIRE((child = fork()) != -1);
47a0f774c8Skamil if (child == 0) {
48a0f774c8Skamil DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
49a0f774c8Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
50a0f774c8Skamil
51a0f774c8Skamil DPRINTF("Before raising %s from child\n", strsignal(sigval));
52a0f774c8Skamil FORKEE_ASSERT(raise(sigval) == 0);
53a0f774c8Skamil
54a0f774c8Skamil switch (sigval) {
55a0f774c8Skamil case SIGKILL:
56a0f774c8Skamil /* NOTREACHED */
57a0f774c8Skamil FORKEE_ASSERTX(0 && "This shall not be reached");
58a0f774c8Skamil __unreachable();
59a0f774c8Skamil default:
60a0f774c8Skamil DPRINTF("Before exiting of the child process\n");
61a0f774c8Skamil _exit(exitval);
62a0f774c8Skamil }
63a0f774c8Skamil }
64a0f774c8Skamil DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
65a0f774c8Skamil
66a0f774c8Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
67a0f774c8Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
68a0f774c8Skamil
69a0f774c8Skamil switch (sigval) {
70a0f774c8Skamil case SIGKILL:
71a0f774c8Skamil validate_status_signaled(status, sigval, 0);
72a0f774c8Skamil SYSCALL_REQUIRE(
73a0f774c8Skamil ptrace(PT_GET_PROCESS_STATE, child, &state, slen) == -1);
74a0f774c8Skamil
75a0f774c8Skamil break;
76a0f774c8Skamil default:
77a0f774c8Skamil validate_status_stopped(status, sigval);
78a0f774c8Skamil
79a0f774c8Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
80a0f774c8Skamil "child\n");
81a0f774c8Skamil SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info,
82a0f774c8Skamil sizeof(info)) != -1);
83a0f774c8Skamil
84a0f774c8Skamil DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
85a0f774c8Skamil DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
86a0f774c8Skamil "si_errno=%#x\n",
87a0f774c8Skamil info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
88a0f774c8Skamil info.psi_siginfo.si_errno);
89a0f774c8Skamil
90a0f774c8Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
91a0f774c8Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
92a0f774c8Skamil
93*7f74343bSsimonb DPRINTF("Assert that PT_GET_PROCESS_STATE returns non-error\n");
94a0f774c8Skamil SYSCALL_REQUIRE(
95a0f774c8Skamil ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
96a0f774c8Skamil ATF_REQUIRE(memcmp(&state, &zero_state, slen) == 0);
97a0f774c8Skamil
98a0f774c8Skamil DPRINTF("Before resuming the child process where it left off "
99a0f774c8Skamil "and without signal to be sent\n");
100a0f774c8Skamil SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
101a0f774c8Skamil
102a0f774c8Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
103a0f774c8Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
104a0f774c8Skamil child);
105a0f774c8Skamil break;
106a0f774c8Skamil }
107a0f774c8Skamil
108a0f774c8Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
109a0f774c8Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
110a0f774c8Skamil }
111a0f774c8Skamil
112a0f774c8Skamil #define TRACEME_RAISE(test, sig) \
113a0f774c8Skamil ATF_TC(test); \
114a0f774c8Skamil ATF_TC_HEAD(test, tc) \
115a0f774c8Skamil { \
116a0f774c8Skamil atf_tc_set_md_var(tc, "descr", \
117a0f774c8Skamil "Verify " #sig " followed by _exit(2) in a child"); \
118a0f774c8Skamil } \
119a0f774c8Skamil \
120a0f774c8Skamil ATF_TC_BODY(test, tc) \
121a0f774c8Skamil { \
122a0f774c8Skamil \
123a0f774c8Skamil traceme_raise(sig); \
124a0f774c8Skamil }
125a0f774c8Skamil
TRACEME_RAISE(traceme_raise1,SIGKILL)126a0f774c8Skamil TRACEME_RAISE(traceme_raise1, SIGKILL) /* non-maskable */
127a0f774c8Skamil TRACEME_RAISE(traceme_raise2, SIGSTOP) /* non-maskable */
128a0f774c8Skamil TRACEME_RAISE(traceme_raise3, SIGABRT) /* regular abort trap */
129a0f774c8Skamil TRACEME_RAISE(traceme_raise4, SIGHUP) /* hangup */
130a0f774c8Skamil TRACEME_RAISE(traceme_raise5, SIGCONT) /* continued? */
131a0f774c8Skamil TRACEME_RAISE(traceme_raise6, SIGTRAP) /* crash signal */
132a0f774c8Skamil TRACEME_RAISE(traceme_raise7, SIGBUS) /* crash signal */
133a0f774c8Skamil TRACEME_RAISE(traceme_raise8, SIGILL) /* crash signal */
134a0f774c8Skamil TRACEME_RAISE(traceme_raise9, SIGFPE) /* crash signal */
135a0f774c8Skamil TRACEME_RAISE(traceme_raise10, SIGSEGV) /* crash signal */
136a0f774c8Skamil
137a0f774c8Skamil /// ----------------------------------------------------------------------------
138a0f774c8Skamil
139a0f774c8Skamil static void
140a0f774c8Skamil traceme_raisesignal_ignored(int sigignored)
141a0f774c8Skamil {
142a0f774c8Skamil const int exitval = 5;
143a0f774c8Skamil const int sigval = SIGSTOP;
144a0f774c8Skamil pid_t child, wpid;
145a0f774c8Skamil struct sigaction sa;
146a0f774c8Skamil #if defined(TWAIT_HAVE_STATUS)
147a0f774c8Skamil int status;
148a0f774c8Skamil #endif
149a0f774c8Skamil struct ptrace_siginfo info;
150a0f774c8Skamil
151a0f774c8Skamil memset(&info, 0, sizeof(info));
152a0f774c8Skamil
153a0f774c8Skamil DPRINTF("Before forking process PID=%d\n", getpid());
154a0f774c8Skamil SYSCALL_REQUIRE((child = fork()) != -1);
155a0f774c8Skamil if (child == 0) {
156a0f774c8Skamil DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
157a0f774c8Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
158a0f774c8Skamil
159a0f774c8Skamil memset(&sa, 0, sizeof(sa));
160a0f774c8Skamil sa.sa_handler = SIG_IGN;
161a0f774c8Skamil sigemptyset(&sa.sa_mask);
162a0f774c8Skamil FORKEE_ASSERT(sigaction(sigignored, &sa, NULL) != -1);
163a0f774c8Skamil
164a0f774c8Skamil DPRINTF("Before raising %s from child\n", strsignal(sigval));
165a0f774c8Skamil FORKEE_ASSERT(raise(sigval) == 0);
166a0f774c8Skamil
167a0f774c8Skamil DPRINTF("Before raising %s from child\n",
168a0f774c8Skamil strsignal(sigignored));
169a0f774c8Skamil FORKEE_ASSERT(raise(sigignored) == 0);
170a0f774c8Skamil
171a0f774c8Skamil DPRINTF("Before exiting of the child process\n");
172a0f774c8Skamil _exit(exitval);
173a0f774c8Skamil }
174a0f774c8Skamil DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
175a0f774c8Skamil
176a0f774c8Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
177a0f774c8Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
178a0f774c8Skamil
179a0f774c8Skamil validate_status_stopped(status, sigval);
180a0f774c8Skamil
181a0f774c8Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
182a0f774c8Skamil SYSCALL_REQUIRE(
183a0f774c8Skamil ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
184a0f774c8Skamil
185a0f774c8Skamil DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
186a0f774c8Skamil DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
187a0f774c8Skamil info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
188a0f774c8Skamil info.psi_siginfo.si_errno);
189a0f774c8Skamil
190a0f774c8Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
191a0f774c8Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
192a0f774c8Skamil
193a0f774c8Skamil DPRINTF("Before resuming the child process where it left off and "
194a0f774c8Skamil "without signal to be sent\n");
195a0f774c8Skamil SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
196a0f774c8Skamil
197a0f774c8Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
198a0f774c8Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
199a0f774c8Skamil
200a0f774c8Skamil validate_status_stopped(status, sigignored);
201a0f774c8Skamil
202a0f774c8Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
203a0f774c8Skamil SYSCALL_REQUIRE(
204a0f774c8Skamil ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
205a0f774c8Skamil
206a0f774c8Skamil DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
207a0f774c8Skamil DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
208a0f774c8Skamil info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
209a0f774c8Skamil info.psi_siginfo.si_errno);
210a0f774c8Skamil
211a0f774c8Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigignored);
212a0f774c8Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
213a0f774c8Skamil
214a0f774c8Skamil DPRINTF("Before resuming the child process where it left off and "
215a0f774c8Skamil "without signal to be sent\n");
216a0f774c8Skamil SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
217a0f774c8Skamil
218a0f774c8Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
219a0f774c8Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
220a0f774c8Skamil
221a0f774c8Skamil validate_status_exited(status, exitval);
222a0f774c8Skamil
223a0f774c8Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
224a0f774c8Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
225a0f774c8Skamil }
226a0f774c8Skamil
227a0f774c8Skamil #define TRACEME_RAISESIGNAL_IGNORED(test, sig) \
228a0f774c8Skamil ATF_TC(test); \
229a0f774c8Skamil ATF_TC_HEAD(test, tc) \
230a0f774c8Skamil { \
231a0f774c8Skamil atf_tc_set_md_var(tc, "descr", \
232a0f774c8Skamil "Verify that ignoring (with SIG_IGN) " #sig " in tracee " \
233a0f774c8Skamil "does not stop tracer from catching this raised signal"); \
234a0f774c8Skamil } \
235a0f774c8Skamil \
236a0f774c8Skamil ATF_TC_BODY(test, tc) \
237a0f774c8Skamil { \
238a0f774c8Skamil \
239a0f774c8Skamil traceme_raisesignal_ignored(sig); \
240a0f774c8Skamil }
241a0f774c8Skamil
242a0f774c8Skamil // A signal handler for SIGKILL and SIGSTOP cannot be ignored.
TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored1,SIGABRT)243a0f774c8Skamil TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored1, SIGABRT) /* abort */
244a0f774c8Skamil TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored2, SIGHUP) /* hangup */
245a0f774c8Skamil TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored3, SIGCONT) /* cont. */
246a0f774c8Skamil TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored4, SIGTRAP) /* crash */
247a0f774c8Skamil TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored5, SIGBUS) /* crash */
248a0f774c8Skamil TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored6, SIGILL) /* crash */
249a0f774c8Skamil TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored7, SIGFPE) /* crash */
250a0f774c8Skamil TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored8, SIGSEGV) /* crash */
251a0f774c8Skamil
252a0f774c8Skamil /// ----------------------------------------------------------------------------
253a0f774c8Skamil
254a0f774c8Skamil static void
255a0f774c8Skamil traceme_raisesignal_masked(int sigmasked)
256a0f774c8Skamil {
257a0f774c8Skamil const int exitval = 5;
258a0f774c8Skamil const int sigval = SIGSTOP;
259a0f774c8Skamil pid_t child, wpid;
260a0f774c8Skamil #if defined(TWAIT_HAVE_STATUS)
261a0f774c8Skamil int status;
262a0f774c8Skamil #endif
263a0f774c8Skamil sigset_t intmask;
264a0f774c8Skamil struct ptrace_siginfo info;
265a0f774c8Skamil
266a0f774c8Skamil memset(&info, 0, sizeof(info));
267a0f774c8Skamil
268a0f774c8Skamil DPRINTF("Before forking process PID=%d\n", getpid());
269a0f774c8Skamil SYSCALL_REQUIRE((child = fork()) != -1);
270a0f774c8Skamil if (child == 0) {
271a0f774c8Skamil DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
272a0f774c8Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
273a0f774c8Skamil
274a0f774c8Skamil sigemptyset(&intmask);
275a0f774c8Skamil sigaddset(&intmask, sigmasked);
276a0f774c8Skamil sigprocmask(SIG_BLOCK, &intmask, NULL);
277a0f774c8Skamil
278a0f774c8Skamil DPRINTF("Before raising %s from child\n", strsignal(sigval));
279a0f774c8Skamil FORKEE_ASSERT(raise(sigval) == 0);
280a0f774c8Skamil
281a0f774c8Skamil DPRINTF("Before raising %s breakpoint from child\n",
282a0f774c8Skamil strsignal(sigmasked));
283a0f774c8Skamil FORKEE_ASSERT(raise(sigmasked) == 0);
284a0f774c8Skamil
285a0f774c8Skamil DPRINTF("Before exiting of the child process\n");
286a0f774c8Skamil _exit(exitval);
287a0f774c8Skamil }
288a0f774c8Skamil DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
289a0f774c8Skamil
290a0f774c8Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
291a0f774c8Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
292a0f774c8Skamil
293a0f774c8Skamil validate_status_stopped(status, sigval);
294a0f774c8Skamil
295a0f774c8Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
296a0f774c8Skamil SYSCALL_REQUIRE(
297a0f774c8Skamil ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
298a0f774c8Skamil
299a0f774c8Skamil DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
300a0f774c8Skamil DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
301a0f774c8Skamil info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
302a0f774c8Skamil info.psi_siginfo.si_errno);
303a0f774c8Skamil
304a0f774c8Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
305a0f774c8Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
306a0f774c8Skamil
307a0f774c8Skamil DPRINTF("Before resuming the child process where it left off and "
308a0f774c8Skamil "without signal to be sent\n");
309a0f774c8Skamil SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
310a0f774c8Skamil
311a0f774c8Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
312a0f774c8Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
313a0f774c8Skamil
314a0f774c8Skamil validate_status_exited(status, exitval);
315a0f774c8Skamil
316a0f774c8Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
317a0f774c8Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
318a0f774c8Skamil }
319a0f774c8Skamil
320a0f774c8Skamil #define TRACEME_RAISESIGNAL_MASKED(test, sig) \
321a0f774c8Skamil ATF_TC(test); \
322a0f774c8Skamil ATF_TC_HEAD(test, tc) \
323a0f774c8Skamil { \
324a0f774c8Skamil atf_tc_set_md_var(tc, "descr", \
325a0f774c8Skamil "Verify that masking (with SIG_BLOCK) " #sig " in tracee " \
326a0f774c8Skamil "stops tracer from catching this raised signal"); \
327a0f774c8Skamil } \
328a0f774c8Skamil \
329a0f774c8Skamil ATF_TC_BODY(test, tc) \
330a0f774c8Skamil { \
331a0f774c8Skamil \
332a0f774c8Skamil traceme_raisesignal_masked(sig); \
333a0f774c8Skamil }
334a0f774c8Skamil
335a0f774c8Skamil // A signal handler for SIGKILL and SIGSTOP cannot be masked.
TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked1,SIGABRT)336a0f774c8Skamil TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked1, SIGABRT) /* abort trap */
337a0f774c8Skamil TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked2, SIGHUP) /* hangup */
338a0f774c8Skamil TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked3, SIGCONT) /* continued? */
339a0f774c8Skamil TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked4, SIGTRAP) /* crash sig. */
340a0f774c8Skamil TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked5, SIGBUS) /* crash sig. */
341a0f774c8Skamil TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked6, SIGILL) /* crash sig. */
342a0f774c8Skamil TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked7, SIGFPE) /* crash sig. */
343a0f774c8Skamil TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked8, SIGSEGV) /* crash sig. */
344a0f774c8Skamil
345a0f774c8Skamil /// ----------------------------------------------------------------------------
346a0f774c8Skamil
347a0f774c8Skamil static void
348a0f774c8Skamil traceme_crash(int sig)
349a0f774c8Skamil {
350a0f774c8Skamil pid_t child, wpid;
351a0f774c8Skamil #if defined(TWAIT_HAVE_STATUS)
352a0f774c8Skamil int status;
353a0f774c8Skamil #endif
354a0f774c8Skamil struct ptrace_siginfo info;
355a0f774c8Skamil
356a0f774c8Skamil #ifndef PTRACE_ILLEGAL_ASM
357a0f774c8Skamil if (sig == SIGILL)
358a0f774c8Skamil atf_tc_skip("PTRACE_ILLEGAL_ASM not defined");
359a0f774c8Skamil #endif
360a0f774c8Skamil
361a0f774c8Skamil if (sig == SIGFPE && !are_fpu_exceptions_supported())
362a0f774c8Skamil atf_tc_skip("FP exceptions are not supported");
363a0f774c8Skamil
364a0f774c8Skamil memset(&info, 0, sizeof(info));
365a0f774c8Skamil
366a0f774c8Skamil DPRINTF("Before forking process PID=%d\n", getpid());
367a0f774c8Skamil SYSCALL_REQUIRE((child = fork()) != -1);
368a0f774c8Skamil if (child == 0) {
369a0f774c8Skamil DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
370a0f774c8Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
371a0f774c8Skamil
372a0f774c8Skamil DPRINTF("Before executing a trap\n");
373a0f774c8Skamil switch (sig) {
374a0f774c8Skamil case SIGTRAP:
375a0f774c8Skamil trigger_trap();
376a0f774c8Skamil break;
377a0f774c8Skamil case SIGSEGV:
378a0f774c8Skamil trigger_segv();
379a0f774c8Skamil break;
380a0f774c8Skamil case SIGILL:
381a0f774c8Skamil trigger_ill();
382a0f774c8Skamil break;
383a0f774c8Skamil case SIGFPE:
384a0f774c8Skamil trigger_fpe();
385a0f774c8Skamil break;
386a0f774c8Skamil case SIGBUS:
387a0f774c8Skamil trigger_bus();
388a0f774c8Skamil break;
389a0f774c8Skamil default:
390a0f774c8Skamil /* NOTREACHED */
391a0f774c8Skamil FORKEE_ASSERTX(0 && "This shall not be reached");
392a0f774c8Skamil }
393a0f774c8Skamil
394a0f774c8Skamil /* NOTREACHED */
395a0f774c8Skamil FORKEE_ASSERTX(0 && "This shall not be reached");
396a0f774c8Skamil }
397a0f774c8Skamil DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
398a0f774c8Skamil
399a0f774c8Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
400a0f774c8Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
401a0f774c8Skamil
402a0f774c8Skamil validate_status_stopped(status, sig);
403a0f774c8Skamil
404*7f74343bSsimonb DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
405a0f774c8Skamil SYSCALL_REQUIRE(
406a0f774c8Skamil ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
407a0f774c8Skamil
408a0f774c8Skamil DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
409a0f774c8Skamil DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
410a0f774c8Skamil info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
411a0f774c8Skamil info.psi_siginfo.si_errno);
412a0f774c8Skamil
413a0f774c8Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sig);
414a0f774c8Skamil switch (sig) {
415a0f774c8Skamil case SIGTRAP:
416a0f774c8Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_BRKPT);
417a0f774c8Skamil break;
418a0f774c8Skamil case SIGSEGV:
419a0f774c8Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SEGV_MAPERR);
420a0f774c8Skamil break;
421a0f774c8Skamil case SIGILL:
422a0f774c8Skamil ATF_REQUIRE(info.psi_siginfo.si_code >= ILL_ILLOPC &&
423a0f774c8Skamil info.psi_siginfo.si_code <= ILL_BADSTK);
424a0f774c8Skamil break;
425a0f774c8Skamil case SIGFPE:
426c3c8ab88Srin // XXXQEMU ATF_REQUIRE_EQ(info.psi_siginfo.si_code, FPE_FLTDIV);
427a0f774c8Skamil break;
428a0f774c8Skamil case SIGBUS:
429a0f774c8Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, BUS_ADRERR);
430a0f774c8Skamil break;
431a0f774c8Skamil }
432a0f774c8Skamil
433a0f774c8Skamil SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1);
434a0f774c8Skamil
435a0f774c8Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
436a0f774c8Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
437a0f774c8Skamil
438a0f774c8Skamil validate_status_signaled(status, SIGKILL, 0);
439a0f774c8Skamil
440a0f774c8Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
441a0f774c8Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
442a0f774c8Skamil }
443a0f774c8Skamil
444a0f774c8Skamil #define TRACEME_CRASH(test, sig) \
445a0f774c8Skamil ATF_TC(test); \
446a0f774c8Skamil ATF_TC_HEAD(test, tc) \
447a0f774c8Skamil { \
448a0f774c8Skamil atf_tc_set_md_var(tc, "descr", \
449a0f774c8Skamil "Verify crash signal " #sig " in a child after PT_TRACE_ME"); \
450a0f774c8Skamil } \
451a0f774c8Skamil \
452a0f774c8Skamil ATF_TC_BODY(test, tc) \
453a0f774c8Skamil { \
454a0f774c8Skamil \
455a0f774c8Skamil traceme_crash(sig); \
456a0f774c8Skamil }
457a0f774c8Skamil
TRACEME_CRASH(traceme_crash_trap,SIGTRAP)458a0f774c8Skamil TRACEME_CRASH(traceme_crash_trap, SIGTRAP)
459a0f774c8Skamil TRACEME_CRASH(traceme_crash_segv, SIGSEGV)
460a0f774c8Skamil TRACEME_CRASH(traceme_crash_ill, SIGILL)
461a0f774c8Skamil TRACEME_CRASH(traceme_crash_fpe, SIGFPE)
462a0f774c8Skamil TRACEME_CRASH(traceme_crash_bus, SIGBUS)
463a0f774c8Skamil
464a0f774c8Skamil /// ----------------------------------------------------------------------------
465a0f774c8Skamil
466a0f774c8Skamil static void
467a0f774c8Skamil traceme_signalmasked_crash(int sig)
468a0f774c8Skamil {
469a0f774c8Skamil const int sigval = SIGSTOP;
470a0f774c8Skamil pid_t child, wpid;
471a0f774c8Skamil #if defined(TWAIT_HAVE_STATUS)
472a0f774c8Skamil int status;
473a0f774c8Skamil #endif
474a0f774c8Skamil struct ptrace_siginfo info;
475a0f774c8Skamil sigset_t intmask;
476a0f774c8Skamil struct kinfo_proc2 kp;
477a0f774c8Skamil size_t len = sizeof(kp);
478a0f774c8Skamil
479a0f774c8Skamil int name[6];
480a0f774c8Skamil const size_t namelen = __arraycount(name);
481a0f774c8Skamil ki_sigset_t kp_sigmask;
482a0f774c8Skamil
483a0f774c8Skamil #ifndef PTRACE_ILLEGAL_ASM
484a0f774c8Skamil if (sig == SIGILL)
485a0f774c8Skamil atf_tc_skip("PTRACE_ILLEGAL_ASM not defined");
486a0f774c8Skamil #endif
487a0f774c8Skamil
488a0f774c8Skamil if (sig == SIGFPE && !are_fpu_exceptions_supported())
489a0f774c8Skamil atf_tc_skip("FP exceptions are not supported");
490a0f774c8Skamil
491a0f774c8Skamil memset(&info, 0, sizeof(info));
492a0f774c8Skamil
493a0f774c8Skamil DPRINTF("Before forking process PID=%d\n", getpid());
494a0f774c8Skamil SYSCALL_REQUIRE((child = fork()) != -1);
495a0f774c8Skamil if (child == 0) {
496a0f774c8Skamil DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
497a0f774c8Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
498a0f774c8Skamil
499a0f774c8Skamil sigemptyset(&intmask);
500a0f774c8Skamil sigaddset(&intmask, sig);
501a0f774c8Skamil sigprocmask(SIG_BLOCK, &intmask, NULL);
502a0f774c8Skamil
503a0f774c8Skamil DPRINTF("Before raising %s from child\n", strsignal(sigval));
504a0f774c8Skamil FORKEE_ASSERT(raise(sigval) == 0);
505a0f774c8Skamil
506a0f774c8Skamil DPRINTF("Before executing a trap\n");
507a0f774c8Skamil switch (sig) {
508a0f774c8Skamil case SIGTRAP:
509a0f774c8Skamil trigger_trap();
510a0f774c8Skamil break;
511a0f774c8Skamil case SIGSEGV:
512a0f774c8Skamil trigger_segv();
513a0f774c8Skamil break;
514a0f774c8Skamil case SIGILL:
515a0f774c8Skamil trigger_ill();
516a0f774c8Skamil break;
517a0f774c8Skamil case SIGFPE:
518a0f774c8Skamil trigger_fpe();
519a0f774c8Skamil break;
520a0f774c8Skamil case SIGBUS:
521a0f774c8Skamil trigger_bus();
522a0f774c8Skamil break;
523a0f774c8Skamil default:
524a0f774c8Skamil /* NOTREACHED */
525a0f774c8Skamil FORKEE_ASSERTX(0 && "This shall not be reached");
526a0f774c8Skamil }
527a0f774c8Skamil
528a0f774c8Skamil /* NOTREACHED */
529a0f774c8Skamil FORKEE_ASSERTX(0 && "This shall not be reached");
530a0f774c8Skamil }
531a0f774c8Skamil DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
532a0f774c8Skamil
533a0f774c8Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
534a0f774c8Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
535a0f774c8Skamil
536a0f774c8Skamil validate_status_stopped(status, sigval);
537a0f774c8Skamil
538a0f774c8Skamil name[0] = CTL_KERN,
539a0f774c8Skamil name[1] = KERN_PROC2,
540a0f774c8Skamil name[2] = KERN_PROC_PID;
541a0f774c8Skamil name[3] = child;
542a0f774c8Skamil name[4] = sizeof(kp);
543a0f774c8Skamil name[5] = 1;
544a0f774c8Skamil
545a0f774c8Skamil ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
546a0f774c8Skamil
547a0f774c8Skamil kp_sigmask = kp.p_sigmask;
548a0f774c8Skamil
549a0f774c8Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
550a0f774c8Skamil SYSCALL_REQUIRE(
551a0f774c8Skamil ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
552a0f774c8Skamil
553a0f774c8Skamil DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
554a0f774c8Skamil DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
555a0f774c8Skamil info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
556a0f774c8Skamil info.psi_siginfo.si_errno);
557a0f774c8Skamil
558a0f774c8Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
559a0f774c8Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
560a0f774c8Skamil
561a0f774c8Skamil DPRINTF("Before resuming the child process where it left off and "
562a0f774c8Skamil "without signal to be sent\n");
563a0f774c8Skamil SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
564a0f774c8Skamil
565a0f774c8Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
566a0f774c8Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
567a0f774c8Skamil
568a0f774c8Skamil validate_status_stopped(status, sig);
569a0f774c8Skamil
570*7f74343bSsimonb DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
571a0f774c8Skamil SYSCALL_REQUIRE(
572a0f774c8Skamil ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
573a0f774c8Skamil
574a0f774c8Skamil DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
575a0f774c8Skamil DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
576a0f774c8Skamil info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
577a0f774c8Skamil info.psi_siginfo.si_errno);
578a0f774c8Skamil
579a0f774c8Skamil ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
580a0f774c8Skamil
581a0f774c8Skamil DPRINTF("kp_sigmask="
582a0f774c8Skamil "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n",
583a0f774c8Skamil kp_sigmask.__bits[0], kp_sigmask.__bits[1], kp_sigmask.__bits[2],
584a0f774c8Skamil kp_sigmask.__bits[3]);
585a0f774c8Skamil
586a0f774c8Skamil DPRINTF("kp.p_sigmask="
587a0f774c8Skamil "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n",
588a0f774c8Skamil kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1],
589a0f774c8Skamil kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]);
590a0f774c8Skamil
591a0f774c8Skamil ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask, sizeof(kp_sigmask)));
592a0f774c8Skamil
593a0f774c8Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sig);
594a0f774c8Skamil switch (sig) {
595a0f774c8Skamil case SIGTRAP:
596a0f774c8Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_BRKPT);
597a0f774c8Skamil break;
598a0f774c8Skamil case SIGSEGV:
599a0f774c8Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SEGV_MAPERR);
600a0f774c8Skamil break;
601a0f774c8Skamil case SIGILL:
602a0f774c8Skamil ATF_REQUIRE(info.psi_siginfo.si_code >= ILL_ILLOPC &&
603a0f774c8Skamil info.psi_siginfo.si_code <= ILL_BADSTK);
604a0f774c8Skamil break;
605a0f774c8Skamil case SIGFPE:
606c3c8ab88Srin // XXXQEMU ATF_REQUIRE_EQ(info.psi_siginfo.si_code, FPE_FLTDIV);
607a0f774c8Skamil break;
608a0f774c8Skamil case SIGBUS:
609a0f774c8Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, BUS_ADRERR);
610a0f774c8Skamil break;
611a0f774c8Skamil }
612a0f774c8Skamil
613a0f774c8Skamil SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1);
614a0f774c8Skamil
615a0f774c8Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
616a0f774c8Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
617a0f774c8Skamil
618a0f774c8Skamil validate_status_signaled(status, SIGKILL, 0);
619a0f774c8Skamil
620a0f774c8Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
621a0f774c8Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
622a0f774c8Skamil }
623a0f774c8Skamil
624a0f774c8Skamil #define TRACEME_SIGNALMASKED_CRASH(test, sig) \
625a0f774c8Skamil ATF_TC(test); \
626a0f774c8Skamil ATF_TC_HEAD(test, tc) \
627a0f774c8Skamil { \
628a0f774c8Skamil atf_tc_set_md_var(tc, "descr", \
629a0f774c8Skamil "Verify masked crash signal " #sig " in a child after " \
630a0f774c8Skamil "PT_TRACE_ME is delivered to its tracer"); \
631a0f774c8Skamil } \
632a0f774c8Skamil \
633a0f774c8Skamil ATF_TC_BODY(test, tc) \
634a0f774c8Skamil { \
635a0f774c8Skamil \
636a0f774c8Skamil traceme_signalmasked_crash(sig); \
637a0f774c8Skamil }
638a0f774c8Skamil
TRACEME_SIGNALMASKED_CRASH(traceme_signalmasked_crash_trap,SIGTRAP)639a0f774c8Skamil TRACEME_SIGNALMASKED_CRASH(traceme_signalmasked_crash_trap, SIGTRAP)
640a0f774c8Skamil TRACEME_SIGNALMASKED_CRASH(traceme_signalmasked_crash_segv, SIGSEGV)
641a0f774c8Skamil TRACEME_SIGNALMASKED_CRASH(traceme_signalmasked_crash_ill, SIGILL)
642a0f774c8Skamil TRACEME_SIGNALMASKED_CRASH(traceme_signalmasked_crash_fpe, SIGFPE)
643a0f774c8Skamil TRACEME_SIGNALMASKED_CRASH(traceme_signalmasked_crash_bus, SIGBUS)
644a0f774c8Skamil
645a0f774c8Skamil /// ----------------------------------------------------------------------------
646a0f774c8Skamil
647a0f774c8Skamil static void
648a0f774c8Skamil traceme_signalignored_crash(int sig)
649a0f774c8Skamil {
650a0f774c8Skamil const int sigval = SIGSTOP;
651a0f774c8Skamil pid_t child, wpid;
652a0f774c8Skamil #if defined(TWAIT_HAVE_STATUS)
653a0f774c8Skamil int status;
654a0f774c8Skamil #endif
655a0f774c8Skamil struct sigaction sa;
656a0f774c8Skamil struct ptrace_siginfo info;
657a0f774c8Skamil struct kinfo_proc2 kp;
658a0f774c8Skamil size_t len = sizeof(kp);
659a0f774c8Skamil
660a0f774c8Skamil int name[6];
661a0f774c8Skamil const size_t namelen = __arraycount(name);
662a0f774c8Skamil ki_sigset_t kp_sigignore;
663a0f774c8Skamil
664a0f774c8Skamil #ifndef PTRACE_ILLEGAL_ASM
665a0f774c8Skamil if (sig == SIGILL)
666a0f774c8Skamil atf_tc_skip("PTRACE_ILLEGAL_ASM not defined");
667a0f774c8Skamil #endif
668a0f774c8Skamil
669a0f774c8Skamil if (sig == SIGFPE && !are_fpu_exceptions_supported())
670a0f774c8Skamil atf_tc_skip("FP exceptions are not supported");
671a0f774c8Skamil
672a0f774c8Skamil memset(&info, 0, sizeof(info));
673a0f774c8Skamil
674a0f774c8Skamil DPRINTF("Before forking process PID=%d\n", getpid());
675a0f774c8Skamil SYSCALL_REQUIRE((child = fork()) != -1);
676a0f774c8Skamil if (child == 0) {
677a0f774c8Skamil DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
678a0f774c8Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
679a0f774c8Skamil
680a0f774c8Skamil memset(&sa, 0, sizeof(sa));
681a0f774c8Skamil sa.sa_handler = SIG_IGN;
682a0f774c8Skamil sigemptyset(&sa.sa_mask);
683a0f774c8Skamil
684a0f774c8Skamil FORKEE_ASSERT(sigaction(sig, &sa, NULL) != -1);
685a0f774c8Skamil
686a0f774c8Skamil DPRINTF("Before raising %s from child\n", strsignal(sigval));
687a0f774c8Skamil FORKEE_ASSERT(raise(sigval) == 0);
688a0f774c8Skamil
689a0f774c8Skamil DPRINTF("Before executing a trap\n");
690a0f774c8Skamil switch (sig) {
691a0f774c8Skamil case SIGTRAP:
692a0f774c8Skamil trigger_trap();
693a0f774c8Skamil break;
694a0f774c8Skamil case SIGSEGV:
695a0f774c8Skamil trigger_segv();
696a0f774c8Skamil break;
697a0f774c8Skamil case SIGILL:
698a0f774c8Skamil trigger_ill();
699a0f774c8Skamil break;
700a0f774c8Skamil case SIGFPE:
701a0f774c8Skamil trigger_fpe();
702a0f774c8Skamil break;
703a0f774c8Skamil case SIGBUS:
704a0f774c8Skamil trigger_bus();
705a0f774c8Skamil break;
706a0f774c8Skamil default:
707a0f774c8Skamil /* NOTREACHED */
708a0f774c8Skamil FORKEE_ASSERTX(0 && "This shall not be reached");
709a0f774c8Skamil }
710a0f774c8Skamil
711a0f774c8Skamil /* NOTREACHED */
712a0f774c8Skamil FORKEE_ASSERTX(0 && "This shall not be reached");
713a0f774c8Skamil }
714a0f774c8Skamil DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
715a0f774c8Skamil
716a0f774c8Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
717a0f774c8Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
718a0f774c8Skamil
719a0f774c8Skamil validate_status_stopped(status, sigval);
720a0f774c8Skamil
721a0f774c8Skamil name[0] = CTL_KERN,
722a0f774c8Skamil name[1] = KERN_PROC2,
723a0f774c8Skamil name[2] = KERN_PROC_PID;
724a0f774c8Skamil name[3] = child;
725a0f774c8Skamil name[4] = sizeof(kp);
726a0f774c8Skamil name[5] = 1;
727a0f774c8Skamil
728a0f774c8Skamil ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
729a0f774c8Skamil
730a0f774c8Skamil kp_sigignore = kp.p_sigignore;
731a0f774c8Skamil
732a0f774c8Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
733a0f774c8Skamil SYSCALL_REQUIRE(
734a0f774c8Skamil ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
735a0f774c8Skamil
736a0f774c8Skamil DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
737a0f774c8Skamil DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
738a0f774c8Skamil info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
739a0f774c8Skamil info.psi_siginfo.si_errno);
740a0f774c8Skamil
741a0f774c8Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
742a0f774c8Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
743a0f774c8Skamil
744a0f774c8Skamil DPRINTF("Before resuming the child process where it left off and "
745a0f774c8Skamil "without signal to be sent\n");
746a0f774c8Skamil SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
747a0f774c8Skamil
748a0f774c8Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
749a0f774c8Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
750a0f774c8Skamil
751a0f774c8Skamil validate_status_stopped(status, sig);
752a0f774c8Skamil
753*7f74343bSsimonb DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
754a0f774c8Skamil SYSCALL_REQUIRE(
755a0f774c8Skamil ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
756a0f774c8Skamil
757a0f774c8Skamil DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
758a0f774c8Skamil DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
759a0f774c8Skamil info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
760a0f774c8Skamil info.psi_siginfo.si_errno);
761a0f774c8Skamil
762a0f774c8Skamil ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
763a0f774c8Skamil
764a0f774c8Skamil DPRINTF("kp_sigignore="
765a0f774c8Skamil "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n",
766a0f774c8Skamil kp_sigignore.__bits[0], kp_sigignore.__bits[1],
767a0f774c8Skamil kp_sigignore.__bits[2], kp_sigignore.__bits[3]);
768a0f774c8Skamil
769a0f774c8Skamil DPRINTF("kp.p_sigignore="
770a0f774c8Skamil "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n",
771a0f774c8Skamil kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1],
772a0f774c8Skamil kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]);
773a0f774c8Skamil
774a0f774c8Skamil ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore, sizeof(kp_sigignore)));
775a0f774c8Skamil
776a0f774c8Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sig);
777a0f774c8Skamil switch (sig) {
778a0f774c8Skamil case SIGTRAP:
779a0f774c8Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_BRKPT);
780a0f774c8Skamil break;
781a0f774c8Skamil case SIGSEGV:
782a0f774c8Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SEGV_MAPERR);
783a0f774c8Skamil break;
784a0f774c8Skamil case SIGILL:
785a0f774c8Skamil ATF_REQUIRE(info.psi_siginfo.si_code >= ILL_ILLOPC &&
786a0f774c8Skamil info.psi_siginfo.si_code <= ILL_BADSTK);
787a0f774c8Skamil break;
788a0f774c8Skamil case SIGFPE:
789c3c8ab88Srin // XXXQEMU ATF_REQUIRE_EQ(info.psi_siginfo.si_code, FPE_FLTDIV);
790a0f774c8Skamil break;
791a0f774c8Skamil case SIGBUS:
792a0f774c8Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, BUS_ADRERR);
793a0f774c8Skamil break;
794a0f774c8Skamil }
795a0f774c8Skamil
796a0f774c8Skamil SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1);
797a0f774c8Skamil
798a0f774c8Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
799a0f774c8Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
800a0f774c8Skamil
801a0f774c8Skamil validate_status_signaled(status, SIGKILL, 0);
802a0f774c8Skamil
803a0f774c8Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
804a0f774c8Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
805a0f774c8Skamil }
806a0f774c8Skamil
807a0f774c8Skamil #define TRACEME_SIGNALIGNORED_CRASH(test, sig) \
808a0f774c8Skamil ATF_TC(test); \
809a0f774c8Skamil ATF_TC_HEAD(test, tc) \
810a0f774c8Skamil { \
811a0f774c8Skamil atf_tc_set_md_var(tc, "descr", \
812a0f774c8Skamil "Verify ignored crash signal " #sig " in a child after " \
813a0f774c8Skamil "PT_TRACE_ME is delivered to its tracer"); \
814a0f774c8Skamil } \
815a0f774c8Skamil \
816a0f774c8Skamil ATF_TC_BODY(test, tc) \
817a0f774c8Skamil { \
818a0f774c8Skamil \
819a0f774c8Skamil traceme_signalignored_crash(sig); \
820a0f774c8Skamil }
821a0f774c8Skamil
TRACEME_SIGNALIGNORED_CRASH(traceme_signalignored_crash_trap,SIGTRAP)822a0f774c8Skamil TRACEME_SIGNALIGNORED_CRASH(traceme_signalignored_crash_trap, SIGTRAP)
823a0f774c8Skamil TRACEME_SIGNALIGNORED_CRASH(traceme_signalignored_crash_segv, SIGSEGV)
824a0f774c8Skamil TRACEME_SIGNALIGNORED_CRASH(traceme_signalignored_crash_ill, SIGILL)
825a0f774c8Skamil TRACEME_SIGNALIGNORED_CRASH(traceme_signalignored_crash_fpe, SIGFPE)
826a0f774c8Skamil TRACEME_SIGNALIGNORED_CRASH(traceme_signalignored_crash_bus, SIGBUS)
827a0f774c8Skamil
828a0f774c8Skamil /// ----------------------------------------------------------------------------
829a0f774c8Skamil
830a0f774c8Skamil static void
831a0f774c8Skamil traceme_sendsignal_handle(int sigsent, void (*sah)(int a), int *traceme_caught)
832a0f774c8Skamil {
833a0f774c8Skamil const int exitval = 5;
834a0f774c8Skamil const int sigval = SIGSTOP;
835a0f774c8Skamil pid_t child, wpid;
836a0f774c8Skamil struct sigaction sa;
837a0f774c8Skamil #if defined(TWAIT_HAVE_STATUS)
838a0f774c8Skamil int status;
839a0f774c8Skamil #endif
840a0f774c8Skamil struct ptrace_siginfo info;
841a0f774c8Skamil
842a0f774c8Skamil memset(&info, 0, sizeof(info));
843a0f774c8Skamil
844a0f774c8Skamil DPRINTF("Before forking process PID=%d\n", getpid());
845a0f774c8Skamil SYSCALL_REQUIRE((child = fork()) != -1);
846a0f774c8Skamil if (child == 0) {
847a0f774c8Skamil DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
848a0f774c8Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
849a0f774c8Skamil
850a0f774c8Skamil sa.sa_handler = sah;
851a0f774c8Skamil sa.sa_flags = SA_SIGINFO;
852a0f774c8Skamil sigemptyset(&sa.sa_mask);
853a0f774c8Skamil
854a0f774c8Skamil FORKEE_ASSERT(sigaction(sigsent, &sa, NULL) != -1);
855a0f774c8Skamil
856a0f774c8Skamil DPRINTF("Before raising %s from child\n", strsignal(sigval));
857a0f774c8Skamil FORKEE_ASSERT(raise(sigval) == 0);
858a0f774c8Skamil
859a0f774c8Skamil FORKEE_ASSERT_EQ(*traceme_caught, 1);
860a0f774c8Skamil
861a0f774c8Skamil DPRINTF("Before exiting of the child process\n");
862a0f774c8Skamil _exit(exitval);
863a0f774c8Skamil }
864a0f774c8Skamil DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
865a0f774c8Skamil
866a0f774c8Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
867a0f774c8Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
868a0f774c8Skamil
869a0f774c8Skamil validate_status_stopped(status, sigval);
870a0f774c8Skamil
871a0f774c8Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
872a0f774c8Skamil SYSCALL_REQUIRE(
873a0f774c8Skamil ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
874a0f774c8Skamil
875a0f774c8Skamil DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
876a0f774c8Skamil DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
877a0f774c8Skamil info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
878a0f774c8Skamil info.psi_siginfo.si_errno);
879a0f774c8Skamil
880a0f774c8Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
881a0f774c8Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
882a0f774c8Skamil
883a0f774c8Skamil DPRINTF("Before resuming the child process where it left off and with "
884a0f774c8Skamil "signal %s to be sent\n", strsignal(sigsent));
885a0f774c8Skamil SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1);
886a0f774c8Skamil
887a0f774c8Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
888a0f774c8Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
889a0f774c8Skamil
890a0f774c8Skamil validate_status_exited(status, exitval);
891a0f774c8Skamil
892a0f774c8Skamil DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME);
893a0f774c8Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
894a0f774c8Skamil }
895a0f774c8Skamil
896a0f774c8Skamil #define TRACEME_SENDSIGNAL_HANDLE(test, sig) \
897a0f774c8Skamil ATF_TC(test); \
898a0f774c8Skamil ATF_TC_HEAD(test, tc) \
899a0f774c8Skamil { \
900a0f774c8Skamil atf_tc_set_md_var(tc, "descr", \
901a0f774c8Skamil "Verify that a signal " #sig " emitted by a tracer to a child is " \
902a0f774c8Skamil "handled correctly and caught by a signal handler"); \
903a0f774c8Skamil } \
904a0f774c8Skamil \
905a0f774c8Skamil static int test##_caught = 0; \
906a0f774c8Skamil \
907a0f774c8Skamil static void \
908a0f774c8Skamil test##_sighandler(int arg) \
909a0f774c8Skamil { \
910a0f774c8Skamil FORKEE_ASSERT_EQ(arg, sig); \
911a0f774c8Skamil \
912a0f774c8Skamil ++ test##_caught; \
913a0f774c8Skamil } \
914a0f774c8Skamil \
915a0f774c8Skamil ATF_TC_BODY(test, tc) \
916a0f774c8Skamil { \
917a0f774c8Skamil \
918a0f774c8Skamil traceme_sendsignal_handle(sig, test##_sighandler, & test##_caught); \
919a0f774c8Skamil }
920a0f774c8Skamil
921a0f774c8Skamil // A signal handler for SIGKILL and SIGSTOP cannot be registered.
TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle1,SIGABRT)922a0f774c8Skamil TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle1, SIGABRT) /* abort trap */
923a0f774c8Skamil TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle2, SIGHUP) /* hangup */
924a0f774c8Skamil TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle3, SIGCONT) /* continued? */
925a0f774c8Skamil TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle4, SIGTRAP) /* crash sig. */
926a0f774c8Skamil TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle5, SIGBUS) /* crash sig. */
927a0f774c8Skamil TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle6, SIGILL) /* crash sig. */
928a0f774c8Skamil TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle7, SIGFPE) /* crash sig. */
929a0f774c8Skamil TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle8, SIGSEGV) /* crash sig. */
930a0f774c8Skamil
931a0f774c8Skamil /// ----------------------------------------------------------------------------
932a0f774c8Skamil
933a0f774c8Skamil static void
934a0f774c8Skamil traceme_sendsignal_masked(int sigsent)
935a0f774c8Skamil {
936a0f774c8Skamil const int exitval = 5;
937a0f774c8Skamil const int sigval = SIGSTOP;
938a0f774c8Skamil pid_t child, wpid;
939a0f774c8Skamil sigset_t set;
940a0f774c8Skamil #if defined(TWAIT_HAVE_STATUS)
941a0f774c8Skamil int status;
942a0f774c8Skamil #endif
943a0f774c8Skamil struct ptrace_siginfo info;
944a0f774c8Skamil
945a0f774c8Skamil memset(&info, 0, sizeof(info));
946a0f774c8Skamil
947a0f774c8Skamil DPRINTF("Before forking process PID=%d\n", getpid());
948a0f774c8Skamil SYSCALL_REQUIRE((child = fork()) != -1);
949a0f774c8Skamil if (child == 0) {
950a0f774c8Skamil DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
951a0f774c8Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
952a0f774c8Skamil
953a0f774c8Skamil sigemptyset(&set);
954a0f774c8Skamil sigaddset(&set, sigsent);
955a0f774c8Skamil FORKEE_ASSERT(sigprocmask(SIG_BLOCK, &set, NULL) != -1);
956a0f774c8Skamil
957a0f774c8Skamil DPRINTF("Before raising %s from child\n", strsignal(sigval));
958a0f774c8Skamil FORKEE_ASSERT(raise(sigval) == 0);
959a0f774c8Skamil
960a0f774c8Skamil _exit(exitval);
961a0f774c8Skamil }
962a0f774c8Skamil DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
963a0f774c8Skamil
964a0f774c8Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
965a0f774c8Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
966a0f774c8Skamil
967a0f774c8Skamil validate_status_stopped(status, sigval);
968a0f774c8Skamil
969a0f774c8Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
970a0f774c8Skamil SYSCALL_REQUIRE(
971a0f774c8Skamil ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
972a0f774c8Skamil
973a0f774c8Skamil DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
974a0f774c8Skamil DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
975a0f774c8Skamil info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
976a0f774c8Skamil info.psi_siginfo.si_errno);
977a0f774c8Skamil
978a0f774c8Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
979a0f774c8Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
980a0f774c8Skamil
981a0f774c8Skamil DPRINTF("Before resuming the child process where it left off and with "
982a0f774c8Skamil "signal %s to be sent\n", strsignal(sigsent));
983a0f774c8Skamil SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1);
984a0f774c8Skamil
985a0f774c8Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
986a0f774c8Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
987a0f774c8Skamil
988a0f774c8Skamil validate_status_exited(status, exitval);
989a0f774c8Skamil
990a0f774c8Skamil DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME);
991a0f774c8Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
992a0f774c8Skamil }
993a0f774c8Skamil
994a0f774c8Skamil #define TRACEME_SENDSIGNAL_MASKED(test, sig) \
995a0f774c8Skamil ATF_TC(test); \
996a0f774c8Skamil ATF_TC_HEAD(test, tc) \
997a0f774c8Skamil { \
998a0f774c8Skamil atf_tc_set_md_var(tc, "descr", \
999a0f774c8Skamil "Verify that a signal " #sig " emitted by a tracer to a child is " \
1000a0f774c8Skamil "handled correctly and the signal is masked by SIG_BLOCK"); \
1001a0f774c8Skamil } \
1002a0f774c8Skamil \
1003a0f774c8Skamil ATF_TC_BODY(test, tc) \
1004a0f774c8Skamil { \
1005a0f774c8Skamil \
1006a0f774c8Skamil traceme_sendsignal_masked(sig); \
1007a0f774c8Skamil }
1008a0f774c8Skamil
1009a0f774c8Skamil // A signal handler for SIGKILL and SIGSTOP cannot be masked.
TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked1,SIGABRT)1010a0f774c8Skamil TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked1, SIGABRT) /* abort trap */
1011a0f774c8Skamil TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked2, SIGHUP) /* hangup */
1012a0f774c8Skamil TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked3, SIGCONT) /* continued? */
1013a0f774c8Skamil TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked4, SIGTRAP) /* crash sig. */
1014a0f774c8Skamil TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked5, SIGBUS) /* crash sig. */
1015a0f774c8Skamil TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked6, SIGILL) /* crash sig. */
1016a0f774c8Skamil TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked7, SIGFPE) /* crash sig. */
1017a0f774c8Skamil TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked8, SIGSEGV) /* crash sig. */
1018a0f774c8Skamil
1019a0f774c8Skamil /// ----------------------------------------------------------------------------
1020a0f774c8Skamil
1021a0f774c8Skamil static void
1022a0f774c8Skamil traceme_sendsignal_ignored(int sigsent)
1023a0f774c8Skamil {
1024a0f774c8Skamil const int exitval = 5;
1025a0f774c8Skamil const int sigval = SIGSTOP;
1026a0f774c8Skamil pid_t child, wpid;
1027a0f774c8Skamil struct sigaction sa;
1028a0f774c8Skamil #if defined(TWAIT_HAVE_STATUS)
1029a0f774c8Skamil int status;
1030a0f774c8Skamil #endif
1031a0f774c8Skamil struct ptrace_siginfo info;
1032a0f774c8Skamil
1033a0f774c8Skamil memset(&info, 0, sizeof(info));
1034a0f774c8Skamil
1035a0f774c8Skamil DPRINTF("Before forking process PID=%d\n", getpid());
1036a0f774c8Skamil SYSCALL_REQUIRE((child = fork()) != -1);
1037a0f774c8Skamil if (child == 0) {
1038a0f774c8Skamil DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1039a0f774c8Skamil
1040a0f774c8Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1041a0f774c8Skamil
1042a0f774c8Skamil memset(&sa, 0, sizeof(sa));
1043a0f774c8Skamil sa.sa_handler = SIG_IGN;
1044a0f774c8Skamil sigemptyset(&sa.sa_mask);
1045a0f774c8Skamil FORKEE_ASSERT(sigaction(sigsent, &sa, NULL) != -1);
1046a0f774c8Skamil
1047a0f774c8Skamil DPRINTF("Before raising %s from child\n", strsignal(sigval));
1048a0f774c8Skamil FORKEE_ASSERT(raise(sigval) == 0);
1049a0f774c8Skamil
1050a0f774c8Skamil _exit(exitval);
1051a0f774c8Skamil }
1052a0f774c8Skamil DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1053a0f774c8Skamil
1054a0f774c8Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1055a0f774c8Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1056a0f774c8Skamil
1057a0f774c8Skamil validate_status_stopped(status, sigval);
1058a0f774c8Skamil
1059a0f774c8Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
1060a0f774c8Skamil SYSCALL_REQUIRE(
1061a0f774c8Skamil ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
1062a0f774c8Skamil
1063a0f774c8Skamil DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
1064a0f774c8Skamil DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
1065a0f774c8Skamil info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
1066a0f774c8Skamil info.psi_siginfo.si_errno);
1067a0f774c8Skamil
1068a0f774c8Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
1069a0f774c8Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
1070a0f774c8Skamil
1071a0f774c8Skamil DPRINTF("Before resuming the child process where it left off and with "
1072a0f774c8Skamil "signal %s to be sent\n", strsignal(sigsent));
1073a0f774c8Skamil SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1);
1074a0f774c8Skamil
1075a0f774c8Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1076a0f774c8Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1077a0f774c8Skamil
1078a0f774c8Skamil validate_status_exited(status, exitval);
1079a0f774c8Skamil
1080a0f774c8Skamil DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME);
1081a0f774c8Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1082a0f774c8Skamil }
1083a0f774c8Skamil
1084a0f774c8Skamil #define TRACEME_SENDSIGNAL_IGNORED(test, sig) \
1085a0f774c8Skamil ATF_TC(test); \
1086a0f774c8Skamil ATF_TC_HEAD(test, tc) \
1087a0f774c8Skamil { \
1088a0f774c8Skamil atf_tc_set_md_var(tc, "descr", \
1089a0f774c8Skamil "Verify that a signal " #sig " emitted by a tracer to a child is " \
1090a0f774c8Skamil "handled correctly and the signal is masked by SIG_IGN"); \
1091a0f774c8Skamil } \
1092a0f774c8Skamil \
1093a0f774c8Skamil ATF_TC_BODY(test, tc) \
1094a0f774c8Skamil { \
1095a0f774c8Skamil \
1096a0f774c8Skamil traceme_sendsignal_ignored(sig); \
1097a0f774c8Skamil }
1098a0f774c8Skamil
1099a0f774c8Skamil // A signal handler for SIGKILL and SIGSTOP cannot be ignored.
TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored1,SIGABRT)1100a0f774c8Skamil TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored1, SIGABRT) /* abort */
1101a0f774c8Skamil TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored2, SIGHUP) /* hangup */
1102a0f774c8Skamil TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored3, SIGCONT) /* continued */
1103a0f774c8Skamil TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored4, SIGTRAP) /* crash s. */
1104a0f774c8Skamil TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored5, SIGBUS) /* crash s. */
1105a0f774c8Skamil TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored6, SIGILL) /* crash s. */
1106a0f774c8Skamil TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored7, SIGFPE) /* crash s. */
1107a0f774c8Skamil TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored8, SIGSEGV) /* crash s. */
1108a0f774c8Skamil
1109a0f774c8Skamil /// ----------------------------------------------------------------------------
1110a0f774c8Skamil
1111a0f774c8Skamil static void
1112a0f774c8Skamil traceme_sendsignal_simple(int sigsent)
1113a0f774c8Skamil {
1114a0f774c8Skamil const int sigval = SIGSTOP;
1115a0f774c8Skamil int exitval = 0;
1116a0f774c8Skamil pid_t child, wpid;
1117a0f774c8Skamil #if defined(TWAIT_HAVE_STATUS)
1118a0f774c8Skamil int status;
1119a0f774c8Skamil int expect_core;
1120a0f774c8Skamil
1121a0f774c8Skamil switch (sigsent) {
1122a0f774c8Skamil case SIGABRT:
1123a0f774c8Skamil case SIGTRAP:
1124a0f774c8Skamil case SIGBUS:
1125a0f774c8Skamil case SIGILL:
1126a0f774c8Skamil case SIGFPE:
1127a0f774c8Skamil case SIGSEGV:
1128a0f774c8Skamil expect_core = 1;
1129a0f774c8Skamil break;
1130a0f774c8Skamil default:
1131a0f774c8Skamil expect_core = 0;
1132a0f774c8Skamil break;
1133a0f774c8Skamil }
1134a0f774c8Skamil #endif
1135a0f774c8Skamil struct ptrace_siginfo info;
1136a0f774c8Skamil
1137a0f774c8Skamil memset(&info, 0, sizeof(info));
1138a0f774c8Skamil
1139a0f774c8Skamil DPRINTF("Before forking process PID=%d\n", getpid());
1140a0f774c8Skamil SYSCALL_REQUIRE((child = fork()) != -1);
1141a0f774c8Skamil if (child == 0) {
1142a0f774c8Skamil DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1143a0f774c8Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1144a0f774c8Skamil
1145a0f774c8Skamil DPRINTF("Before raising %s from child\n", strsignal(sigval));
1146a0f774c8Skamil FORKEE_ASSERT(raise(sigval) == 0);
1147a0f774c8Skamil
1148a0f774c8Skamil switch (sigsent) {
1149a0f774c8Skamil case SIGCONT:
1150a0f774c8Skamil case SIGSTOP:
1151a0f774c8Skamil _exit(exitval);
1152a0f774c8Skamil default:
1153a0f774c8Skamil /* NOTREACHED */
1154a0f774c8Skamil FORKEE_ASSERTX(0 && "This shall not be reached");
1155a0f774c8Skamil }
1156a0f774c8Skamil }
1157a0f774c8Skamil DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1158a0f774c8Skamil
1159a0f774c8Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1160a0f774c8Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1161a0f774c8Skamil
1162a0f774c8Skamil validate_status_stopped(status, sigval);
1163a0f774c8Skamil
1164a0f774c8Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
1165a0f774c8Skamil SYSCALL_REQUIRE(
1166a0f774c8Skamil ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
1167a0f774c8Skamil
1168a0f774c8Skamil DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
1169a0f774c8Skamil DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
1170a0f774c8Skamil info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
1171a0f774c8Skamil info.psi_siginfo.si_errno);
1172a0f774c8Skamil
1173a0f774c8Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
1174a0f774c8Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
1175a0f774c8Skamil
1176a0f774c8Skamil DPRINTF("Before resuming the child process where it left off and with "
1177a0f774c8Skamil "signal %s to be sent\n", strsignal(sigsent));
1178a0f774c8Skamil SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1);
1179a0f774c8Skamil
1180a0f774c8Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1181a0f774c8Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1182a0f774c8Skamil
1183a0f774c8Skamil switch (sigsent) {
1184a0f774c8Skamil case SIGSTOP:
1185a0f774c8Skamil validate_status_stopped(status, sigsent);
1186a0f774c8Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
1187a0f774c8Skamil "child\n");
1188a0f774c8Skamil SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info,
1189a0f774c8Skamil sizeof(info)) != -1);
1190a0f774c8Skamil
1191a0f774c8Skamil DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
1192a0f774c8Skamil DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
1193a0f774c8Skamil "si_errno=%#x\n",
1194a0f774c8Skamil info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
1195a0f774c8Skamil info.psi_siginfo.si_errno);
1196a0f774c8Skamil
1197a0f774c8Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
1198a0f774c8Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
1199a0f774c8Skamil
1200a0f774c8Skamil DPRINTF("Before resuming the child process where it left off "
1201a0f774c8Skamil "and with signal %s to be sent\n", strsignal(sigsent));
1202a0f774c8Skamil SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1203a0f774c8Skamil
1204a0f774c8Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1205a0f774c8Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
1206a0f774c8Skamil child);
1207a0f774c8Skamil /* FALLTHROUGH */
1208a0f774c8Skamil case SIGCONT:
1209a0f774c8Skamil validate_status_exited(status, exitval);
1210a0f774c8Skamil break;
1211a0f774c8Skamil default:
1212a0f774c8Skamil validate_status_signaled(status, sigsent, expect_core);
1213a0f774c8Skamil break;
1214a0f774c8Skamil }
1215a0f774c8Skamil
1216a0f774c8Skamil DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME);
1217a0f774c8Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1218a0f774c8Skamil }
1219a0f774c8Skamil
1220a0f774c8Skamil #define TRACEME_SENDSIGNAL_SIMPLE(test, sig) \
1221a0f774c8Skamil ATF_TC(test); \
1222a0f774c8Skamil ATF_TC_HEAD(test, tc) \
1223a0f774c8Skamil { \
1224a0f774c8Skamil atf_tc_set_md_var(tc, "descr", \
1225a0f774c8Skamil "Verify that a signal " #sig " emitted by a tracer to a child is " \
1226a0f774c8Skamil "handled correctly in a child without a signal handler"); \
1227a0f774c8Skamil } \
1228a0f774c8Skamil \
1229a0f774c8Skamil ATF_TC_BODY(test, tc) \
1230a0f774c8Skamil { \
1231a0f774c8Skamil \
1232a0f774c8Skamil traceme_sendsignal_simple(sig); \
1233a0f774c8Skamil }
1234a0f774c8Skamil
TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple1,SIGKILL)1235a0f774c8Skamil TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple1, SIGKILL) /* non-maskable*/
1236a0f774c8Skamil TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple2, SIGSTOP) /* non-maskable*/
1237a0f774c8Skamil TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple3, SIGABRT) /* abort trap */
1238a0f774c8Skamil TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple4, SIGHUP) /* hangup */
1239a0f774c8Skamil TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple5, SIGCONT) /* continued? */
1240a0f774c8Skamil TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple6, SIGTRAP) /* crash sig. */
1241a0f774c8Skamil TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple7, SIGBUS) /* crash sig. */
1242a0f774c8Skamil TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple8, SIGILL) /* crash sig. */
1243a0f774c8Skamil TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple9, SIGFPE) /* crash sig. */
1244a0f774c8Skamil TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple10, SIGSEGV) /* crash sig. */
1245a0f774c8Skamil
1246a0f774c8Skamil /// ----------------------------------------------------------------------------
1247a0f774c8Skamil
1248a0f774c8Skamil static void
1249a0f774c8Skamil traceme_vfork_raise(int sigval)
1250a0f774c8Skamil {
1251a0f774c8Skamil const int exitval = 5, exitval_watcher = 10;
1252a0f774c8Skamil pid_t child, parent, watcher, wpid;
1253a0f774c8Skamil int rv;
1254a0f774c8Skamil #if defined(TWAIT_HAVE_STATUS)
1255a0f774c8Skamil int status;
1256a0f774c8Skamil
1257a0f774c8Skamil /* volatile workarounds GCC -Werror=clobbered */
1258a0f774c8Skamil volatile int expect_core;
1259a0f774c8Skamil
1260a0f774c8Skamil switch (sigval) {
1261a0f774c8Skamil case SIGABRT:
1262a0f774c8Skamil case SIGTRAP:
1263a0f774c8Skamil case SIGBUS:
1264a0f774c8Skamil case SIGILL:
1265a0f774c8Skamil case SIGFPE:
1266a0f774c8Skamil case SIGSEGV:
1267a0f774c8Skamil expect_core = 1;
1268a0f774c8Skamil break;
1269a0f774c8Skamil default:
1270a0f774c8Skamil expect_core = 0;
1271a0f774c8Skamil break;
1272a0f774c8Skamil }
1273a0f774c8Skamil #endif
1274a0f774c8Skamil
1275a0f774c8Skamil /*
1276a0f774c8Skamil * Spawn a dedicated thread to watch for a stopped child and emit
1277a0f774c8Skamil * the SIGKILL signal to it.
1278a0f774c8Skamil *
1279a0f774c8Skamil * vfork(2) might clobber watcher, this means that it's safer and
1280a0f774c8Skamil * simpler to reparent this process to initproc and forget about it.
1281a0f774c8Skamil */
1282a0f774c8Skamil if (sigval == SIGSTOP) {
1283a0f774c8Skamil parent = getpid();
1284a0f774c8Skamil
1285a0f774c8Skamil watcher = fork();
1286a0f774c8Skamil ATF_REQUIRE(watcher != 1);
1287a0f774c8Skamil if (watcher == 0) {
1288a0f774c8Skamil /* Double fork(2) trick to reparent to initproc */
1289a0f774c8Skamil watcher = fork();
1290a0f774c8Skamil FORKEE_ASSERT_NEQ(watcher, -1);
1291a0f774c8Skamil if (watcher != 0)
1292a0f774c8Skamil _exit(exitval_watcher);
1293a0f774c8Skamil
1294a0f774c8Skamil child = await_stopped_child(parent);
1295a0f774c8Skamil
1296a0f774c8Skamil errno = 0;
1297a0f774c8Skamil rv = kill(child, SIGKILL);
1298a0f774c8Skamil FORKEE_ASSERT_EQ(rv, 0);
1299a0f774c8Skamil FORKEE_ASSERT_EQ(errno, 0);
1300a0f774c8Skamil
1301a0f774c8Skamil /* This exit value will be collected by initproc */
1302a0f774c8Skamil _exit(0);
1303a0f774c8Skamil }
1304a0f774c8Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1305a0f774c8Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(watcher, &status, 0),
1306a0f774c8Skamil watcher);
1307a0f774c8Skamil
1308a0f774c8Skamil validate_status_exited(status, exitval_watcher);
1309a0f774c8Skamil
1310a0f774c8Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1311a0f774c8Skamil TWAIT_REQUIRE_FAILURE(ECHILD,
1312a0f774c8Skamil wpid = TWAIT_GENERIC(watcher, &status, 0));
1313a0f774c8Skamil }
1314a0f774c8Skamil
1315a0f774c8Skamil DPRINTF("Before forking process PID=%d\n", getpid());
1316a0f774c8Skamil SYSCALL_REQUIRE((child = vfork()) != -1);
1317a0f774c8Skamil if (child == 0) {
1318a0f774c8Skamil DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1319a0f774c8Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1320a0f774c8Skamil
1321a0f774c8Skamil DPRINTF("Before raising %s from child\n", strsignal(sigval));
1322a0f774c8Skamil FORKEE_ASSERT(raise(sigval) == 0);
1323a0f774c8Skamil
1324a0f774c8Skamil switch (sigval) {
1325a0f774c8Skamil case SIGSTOP:
1326a0f774c8Skamil case SIGKILL:
1327a0f774c8Skamil case SIGABRT:
1328a0f774c8Skamil case SIGHUP:
1329a0f774c8Skamil case SIGTRAP:
1330a0f774c8Skamil case SIGBUS:
1331a0f774c8Skamil case SIGILL:
1332a0f774c8Skamil case SIGFPE:
1333a0f774c8Skamil case SIGSEGV:
1334a0f774c8Skamil /* NOTREACHED */
1335a0f774c8Skamil FORKEE_ASSERTX(0 && "This shall not be reached");
1336a0f774c8Skamil __unreachable();
1337a0f774c8Skamil default:
1338a0f774c8Skamil DPRINTF("Before exiting of the child process\n");
1339a0f774c8Skamil _exit(exitval);
1340a0f774c8Skamil }
1341a0f774c8Skamil }
1342a0f774c8Skamil DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1343a0f774c8Skamil
1344a0f774c8Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1345a0f774c8Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1346a0f774c8Skamil
1347a0f774c8Skamil switch (sigval) {
1348a0f774c8Skamil case SIGKILL:
1349a0f774c8Skamil case SIGABRT:
1350a0f774c8Skamil case SIGHUP:
1351a0f774c8Skamil case SIGTRAP:
1352a0f774c8Skamil case SIGBUS:
1353a0f774c8Skamil case SIGILL:
1354a0f774c8Skamil case SIGFPE:
1355a0f774c8Skamil case SIGSEGV:
1356a0f774c8Skamil validate_status_signaled(status, sigval, expect_core);
1357a0f774c8Skamil break;
1358a0f774c8Skamil case SIGSTOP:
1359a0f774c8Skamil validate_status_signaled(status, SIGKILL, 0);
1360a0f774c8Skamil break;
1361a0f774c8Skamil case SIGCONT:
1362a0f774c8Skamil case SIGTSTP:
1363a0f774c8Skamil case SIGTTIN:
1364a0f774c8Skamil case SIGTTOU:
1365a0f774c8Skamil validate_status_exited(status, exitval);
1366a0f774c8Skamil break;
1367a0f774c8Skamil default:
1368a0f774c8Skamil /* NOTREACHED */
1369a0f774c8Skamil ATF_REQUIRE(0 && "NOT IMPLEMENTED");
1370a0f774c8Skamil break;
1371a0f774c8Skamil }
1372a0f774c8Skamil
1373a0f774c8Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1374a0f774c8Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1375a0f774c8Skamil }
1376a0f774c8Skamil
1377a0f774c8Skamil #define TRACEME_VFORK_RAISE(test, sig) \
1378a0f774c8Skamil ATF_TC(test); \
1379a0f774c8Skamil ATF_TC_HEAD(test, tc) \
1380a0f774c8Skamil { \
1381a0f774c8Skamil atf_tc_set_md_var(tc, "descr", \
1382a0f774c8Skamil "Verify PT_TRACE_ME followed by raise of " #sig " in a " \
1383a0f774c8Skamil "vfork(2)ed child"); \
1384a0f774c8Skamil } \
1385a0f774c8Skamil \
1386a0f774c8Skamil ATF_TC_BODY(test, tc) \
1387a0f774c8Skamil { \
1388a0f774c8Skamil \
1389a0f774c8Skamil traceme_vfork_raise(sig); \
1390a0f774c8Skamil }
1391a0f774c8Skamil
TRACEME_VFORK_RAISE(traceme_vfork_raise1,SIGKILL)1392a0f774c8Skamil TRACEME_VFORK_RAISE(traceme_vfork_raise1, SIGKILL) /* non-maskable */
1393a0f774c8Skamil TRACEME_VFORK_RAISE(traceme_vfork_raise2, SIGSTOP) /* non-maskable */
1394a0f774c8Skamil TRACEME_VFORK_RAISE(traceme_vfork_raise3, SIGTSTP) /* ignored in vfork(2) */
1395a0f774c8Skamil TRACEME_VFORK_RAISE(traceme_vfork_raise4, SIGTTIN) /* ignored in vfork(2) */
1396a0f774c8Skamil TRACEME_VFORK_RAISE(traceme_vfork_raise5, SIGTTOU) /* ignored in vfork(2) */
1397a0f774c8Skamil TRACEME_VFORK_RAISE(traceme_vfork_raise6, SIGABRT) /* regular abort trap */
1398a0f774c8Skamil TRACEME_VFORK_RAISE(traceme_vfork_raise7, SIGHUP) /* hangup */
1399a0f774c8Skamil TRACEME_VFORK_RAISE(traceme_vfork_raise8, SIGCONT) /* continued? */
1400a0f774c8Skamil TRACEME_VFORK_RAISE(traceme_vfork_raise9, SIGTRAP) /* crash signal */
1401a0f774c8Skamil TRACEME_VFORK_RAISE(traceme_vfork_raise10, SIGBUS) /* crash signal */
1402a0f774c8Skamil TRACEME_VFORK_RAISE(traceme_vfork_raise11, SIGILL) /* crash signal */
1403a0f774c8Skamil TRACEME_VFORK_RAISE(traceme_vfork_raise12, SIGFPE) /* crash signal */
1404a0f774c8Skamil TRACEME_VFORK_RAISE(traceme_vfork_raise13, SIGSEGV) /* crash signal */
1405a0f774c8Skamil
1406a0f774c8Skamil /// ----------------------------------------------------------------------------
1407a0f774c8Skamil
1408a0f774c8Skamil static void
1409a0f774c8Skamil traceme_vfork_crash(int sig)
1410a0f774c8Skamil {
1411a0f774c8Skamil pid_t child, wpid;
1412a0f774c8Skamil #if defined(TWAIT_HAVE_STATUS)
1413a0f774c8Skamil int status;
1414a0f774c8Skamil #endif
1415a0f774c8Skamil
1416a0f774c8Skamil #ifndef PTRACE_ILLEGAL_ASM
1417a0f774c8Skamil if (sig == SIGILL)
1418a0f774c8Skamil atf_tc_skip("PTRACE_ILLEGAL_ASM not defined");
1419a0f774c8Skamil #endif
1420a0f774c8Skamil
1421a0f774c8Skamil if (sig == SIGFPE && !are_fpu_exceptions_supported())
1422a0f774c8Skamil atf_tc_skip("FP exceptions are not supported");
1423a0f774c8Skamil
1424a0f774c8Skamil DPRINTF("Before forking process PID=%d\n", getpid());
1425a0f774c8Skamil SYSCALL_REQUIRE((child = vfork()) != -1);
1426a0f774c8Skamil if (child == 0) {
1427a0f774c8Skamil DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1428a0f774c8Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1429a0f774c8Skamil
1430a0f774c8Skamil DPRINTF("Before executing a trap\n");
1431a0f774c8Skamil switch (sig) {
1432a0f774c8Skamil case SIGTRAP:
1433a0f774c8Skamil trigger_trap();
1434a0f774c8Skamil break;
1435a0f774c8Skamil case SIGSEGV:
1436a0f774c8Skamil trigger_segv();
1437a0f774c8Skamil break;
1438a0f774c8Skamil case SIGILL:
1439a0f774c8Skamil trigger_ill();
1440a0f774c8Skamil break;
1441a0f774c8Skamil case SIGFPE:
1442a0f774c8Skamil trigger_fpe();
1443a0f774c8Skamil break;
1444a0f774c8Skamil case SIGBUS:
1445a0f774c8Skamil trigger_bus();
1446a0f774c8Skamil break;
1447a0f774c8Skamil default:
1448a0f774c8Skamil /* NOTREACHED */
1449a0f774c8Skamil FORKEE_ASSERTX(0 && "This shall not be reached");
1450a0f774c8Skamil }
1451a0f774c8Skamil
1452a0f774c8Skamil /* NOTREACHED */
1453a0f774c8Skamil FORKEE_ASSERTX(0 && "This shall not be reached");
1454a0f774c8Skamil }
1455a0f774c8Skamil DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1456a0f774c8Skamil
1457a0f774c8Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1458a0f774c8Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1459a0f774c8Skamil
1460a0f774c8Skamil validate_status_signaled(status, sig, 1);
1461a0f774c8Skamil
1462a0f774c8Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1463a0f774c8Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1464a0f774c8Skamil }
1465a0f774c8Skamil
1466a0f774c8Skamil #define TRACEME_VFORK_CRASH(test, sig) \
1467a0f774c8Skamil ATF_TC(test); \
1468a0f774c8Skamil ATF_TC_HEAD(test, tc) \
1469a0f774c8Skamil { \
1470a0f774c8Skamil atf_tc_set_md_var(tc, "descr", \
1471a0f774c8Skamil "Verify PT_TRACE_ME followed by a crash signal " #sig " in a " \
1472a0f774c8Skamil "vfork(2)ed child"); \
1473a0f774c8Skamil } \
1474a0f774c8Skamil \
1475a0f774c8Skamil ATF_TC_BODY(test, tc) \
1476a0f774c8Skamil { \
1477a0f774c8Skamil \
1478a0f774c8Skamil traceme_vfork_crash(sig); \
1479a0f774c8Skamil }
1480a0f774c8Skamil
TRACEME_VFORK_CRASH(traceme_vfork_crash_trap,SIGTRAP)1481a0f774c8Skamil TRACEME_VFORK_CRASH(traceme_vfork_crash_trap, SIGTRAP)
1482a0f774c8Skamil TRACEME_VFORK_CRASH(traceme_vfork_crash_segv, SIGSEGV)
1483a0f774c8Skamil TRACEME_VFORK_CRASH(traceme_vfork_crash_ill, SIGILL)
1484a0f774c8Skamil TRACEME_VFORK_CRASH(traceme_vfork_crash_fpe, SIGFPE)
1485a0f774c8Skamil TRACEME_VFORK_CRASH(traceme_vfork_crash_bus, SIGBUS)
1486a0f774c8Skamil
1487a0f774c8Skamil /// ----------------------------------------------------------------------------
1488a0f774c8Skamil
1489a0f774c8Skamil static void
1490a0f774c8Skamil traceme_vfork_signalmasked_crash(int sig)
1491a0f774c8Skamil {
1492a0f774c8Skamil pid_t child, wpid;
1493a0f774c8Skamil #if defined(TWAIT_HAVE_STATUS)
1494a0f774c8Skamil int status;
1495a0f774c8Skamil #endif
1496a0f774c8Skamil sigset_t intmask;
1497a0f774c8Skamil
1498a0f774c8Skamil #ifndef PTRACE_ILLEGAL_ASM
1499a0f774c8Skamil if (sig == SIGILL)
1500a0f774c8Skamil atf_tc_skip("PTRACE_ILLEGAL_ASM not defined");
1501a0f774c8Skamil #endif
1502a0f774c8Skamil
1503a0f774c8Skamil if (sig == SIGFPE && !are_fpu_exceptions_supported())
1504a0f774c8Skamil atf_tc_skip("FP exceptions are not supported");
1505a0f774c8Skamil
1506a0f774c8Skamil DPRINTF("Before forking process PID=%d\n", getpid());
1507a0f774c8Skamil SYSCALL_REQUIRE((child = vfork()) != -1);
1508a0f774c8Skamil if (child == 0) {
1509a0f774c8Skamil DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1510a0f774c8Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1511a0f774c8Skamil
1512a0f774c8Skamil sigemptyset(&intmask);
1513a0f774c8Skamil sigaddset(&intmask, sig);
1514a0f774c8Skamil sigprocmask(SIG_BLOCK, &intmask, NULL);
1515a0f774c8Skamil
1516a0f774c8Skamil DPRINTF("Before executing a trap\n");
1517a0f774c8Skamil switch (sig) {
1518a0f774c8Skamil case SIGTRAP:
1519a0f774c8Skamil trigger_trap();
1520a0f774c8Skamil break;
1521a0f774c8Skamil case SIGSEGV:
1522a0f774c8Skamil trigger_segv();
1523a0f774c8Skamil break;
1524a0f774c8Skamil case SIGILL:
1525a0f774c8Skamil trigger_ill();
1526a0f774c8Skamil break;
1527a0f774c8Skamil case SIGFPE:
1528a0f774c8Skamil trigger_fpe();
1529a0f774c8Skamil break;
1530a0f774c8Skamil case SIGBUS:
1531a0f774c8Skamil trigger_bus();
1532a0f774c8Skamil break;
1533a0f774c8Skamil default:
1534a0f774c8Skamil /* NOTREACHED */
1535a0f774c8Skamil FORKEE_ASSERTX(0 && "This shall not be reached");
1536a0f774c8Skamil }
1537a0f774c8Skamil
1538a0f774c8Skamil /* NOTREACHED */
1539a0f774c8Skamil FORKEE_ASSERTX(0 && "This shall not be reached");
1540a0f774c8Skamil }
1541a0f774c8Skamil DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1542a0f774c8Skamil
1543a0f774c8Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1544a0f774c8Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1545a0f774c8Skamil
1546a0f774c8Skamil validate_status_signaled(status, sig, 1);
1547a0f774c8Skamil
1548a0f774c8Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1549a0f774c8Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1550a0f774c8Skamil }
1551a0f774c8Skamil
1552a0f774c8Skamil #define TRACEME_VFORK_SIGNALMASKED_CRASH(test, sig) \
1553a0f774c8Skamil ATF_TC(test); \
1554a0f774c8Skamil ATF_TC_HEAD(test, tc) \
1555a0f774c8Skamil { \
1556a0f774c8Skamil atf_tc_set_md_var(tc, "descr", \
1557a0f774c8Skamil "Verify PT_TRACE_ME followed by a crash signal " #sig " in a " \
1558a0f774c8Skamil "vfork(2)ed child with a masked signal"); \
1559a0f774c8Skamil } \
1560a0f774c8Skamil \
1561a0f774c8Skamil ATF_TC_BODY(test, tc) \
1562a0f774c8Skamil { \
1563a0f774c8Skamil \
1564a0f774c8Skamil traceme_vfork_signalmasked_crash(sig); \
1565a0f774c8Skamil }
1566a0f774c8Skamil
TRACEME_VFORK_SIGNALMASKED_CRASH(traceme_vfork_signalmasked_crash_trap,SIGTRAP)1567a0f774c8Skamil TRACEME_VFORK_SIGNALMASKED_CRASH(traceme_vfork_signalmasked_crash_trap, SIGTRAP)
1568a0f774c8Skamil TRACEME_VFORK_SIGNALMASKED_CRASH(traceme_vfork_signalmasked_crash_segv, SIGSEGV)
1569a0f774c8Skamil TRACEME_VFORK_SIGNALMASKED_CRASH(traceme_vfork_signalmasked_crash_ill, SIGILL)
1570a0f774c8Skamil TRACEME_VFORK_SIGNALMASKED_CRASH(traceme_vfork_signalmasked_crash_fpe, SIGFPE)
1571a0f774c8Skamil TRACEME_VFORK_SIGNALMASKED_CRASH(traceme_vfork_signalmasked_crash_bus, SIGBUS)
1572a0f774c8Skamil
1573a0f774c8Skamil /// ----------------------------------------------------------------------------
1574a0f774c8Skamil
1575a0f774c8Skamil static void
1576a0f774c8Skamil traceme_vfork_signalignored_crash(int sig)
1577a0f774c8Skamil {
1578a0f774c8Skamil pid_t child, wpid;
1579a0f774c8Skamil #if defined(TWAIT_HAVE_STATUS)
1580a0f774c8Skamil int status;
1581a0f774c8Skamil #endif
1582a0f774c8Skamil struct sigaction sa;
1583a0f774c8Skamil
1584a0f774c8Skamil #ifndef PTRACE_ILLEGAL_ASM
1585a0f774c8Skamil if (sig == SIGILL)
1586a0f774c8Skamil atf_tc_skip("PTRACE_ILLEGAL_ASM not defined");
1587a0f774c8Skamil #endif
1588a0f774c8Skamil
1589a0f774c8Skamil if (sig == SIGFPE && !are_fpu_exceptions_supported())
1590a0f774c8Skamil atf_tc_skip("FP exceptions are not supported");
1591a0f774c8Skamil
1592a0f774c8Skamil DPRINTF("Before forking process PID=%d\n", getpid());
1593a0f774c8Skamil SYSCALL_REQUIRE((child = vfork()) != -1);
1594a0f774c8Skamil if (child == 0) {
1595a0f774c8Skamil DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1596a0f774c8Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1597a0f774c8Skamil
1598a0f774c8Skamil memset(&sa, 0, sizeof(sa));
1599a0f774c8Skamil sa.sa_handler = SIG_IGN;
1600a0f774c8Skamil sigemptyset(&sa.sa_mask);
1601a0f774c8Skamil
1602a0f774c8Skamil FORKEE_ASSERT(sigaction(sig, &sa, NULL) != -1);
1603a0f774c8Skamil
1604a0f774c8Skamil DPRINTF("Before executing a trap\n");
1605a0f774c8Skamil switch (sig) {
1606a0f774c8Skamil case SIGTRAP:
1607a0f774c8Skamil trigger_trap();
1608a0f774c8Skamil break;
1609a0f774c8Skamil case SIGSEGV:
1610a0f774c8Skamil trigger_segv();
1611a0f774c8Skamil break;
1612a0f774c8Skamil case SIGILL:
1613a0f774c8Skamil trigger_ill();
1614a0f774c8Skamil break;
1615a0f774c8Skamil case SIGFPE:
1616a0f774c8Skamil trigger_fpe();
1617a0f774c8Skamil break;
1618a0f774c8Skamil case SIGBUS:
1619a0f774c8Skamil trigger_bus();
1620a0f774c8Skamil break;
1621a0f774c8Skamil default:
1622a0f774c8Skamil /* NOTREACHED */
1623a0f774c8Skamil FORKEE_ASSERTX(0 && "This shall not be reached");
1624a0f774c8Skamil }
1625a0f774c8Skamil
1626a0f774c8Skamil /* NOTREACHED */
1627a0f774c8Skamil FORKEE_ASSERTX(0 && "This shall not be reached");
1628a0f774c8Skamil }
1629a0f774c8Skamil DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1630a0f774c8Skamil
1631a0f774c8Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1632a0f774c8Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1633a0f774c8Skamil
1634a0f774c8Skamil validate_status_signaled(status, sig, 1);
1635a0f774c8Skamil
1636a0f774c8Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1637a0f774c8Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1638a0f774c8Skamil }
1639a0f774c8Skamil
1640a0f774c8Skamil #define TRACEME_VFORK_SIGNALIGNORED_CRASH(test, sig) \
1641a0f774c8Skamil ATF_TC(test); \
1642a0f774c8Skamil ATF_TC_HEAD(test, tc) \
1643a0f774c8Skamil { \
1644a0f774c8Skamil atf_tc_set_md_var(tc, "descr", \
1645a0f774c8Skamil "Verify PT_TRACE_ME followed by a crash signal " #sig " in a " \
1646a0f774c8Skamil "vfork(2)ed child with ignored signal"); \
1647a0f774c8Skamil } \
1648a0f774c8Skamil \
1649a0f774c8Skamil ATF_TC_BODY(test, tc) \
1650a0f774c8Skamil { \
1651a0f774c8Skamil \
1652a0f774c8Skamil traceme_vfork_signalignored_crash(sig); \
1653a0f774c8Skamil }
1654a0f774c8Skamil
TRACEME_VFORK_SIGNALIGNORED_CRASH(traceme_vfork_signalignored_crash_trap,SIGTRAP)1655a0f774c8Skamil TRACEME_VFORK_SIGNALIGNORED_CRASH(traceme_vfork_signalignored_crash_trap,
1656a0f774c8Skamil SIGTRAP)
1657a0f774c8Skamil TRACEME_VFORK_SIGNALIGNORED_CRASH(traceme_vfork_signalignored_crash_segv,
1658a0f774c8Skamil SIGSEGV)
1659a0f774c8Skamil TRACEME_VFORK_SIGNALIGNORED_CRASH(traceme_vfork_signalignored_crash_ill,
1660a0f774c8Skamil SIGILL)
1661a0f774c8Skamil TRACEME_VFORK_SIGNALIGNORED_CRASH(traceme_vfork_signalignored_crash_fpe,
1662a0f774c8Skamil SIGFPE)
1663a0f774c8Skamil TRACEME_VFORK_SIGNALIGNORED_CRASH(traceme_vfork_signalignored_crash_bus,
1664a0f774c8Skamil SIGBUS)
1665a0f774c8Skamil
1666a0f774c8Skamil /// ----------------------------------------------------------------------------
1667a0f774c8Skamil
1668a0f774c8Skamil #if defined(TWAIT_HAVE_PID)
1669a0f774c8Skamil static void
1670a0f774c8Skamil unrelated_tracer_sees_crash(int sig, bool masked, bool ignored)
1671a0f774c8Skamil {
1672a0f774c8Skamil const int sigval = SIGSTOP;
1673a0f774c8Skamil struct msg_fds parent_tracee, parent_tracer;
1674a0f774c8Skamil const int exitval = 10;
1675a0f774c8Skamil pid_t tracee, tracer, wpid;
1676a0f774c8Skamil uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
1677a0f774c8Skamil #if defined(TWAIT_HAVE_STATUS)
1678a0f774c8Skamil int status;
1679a0f774c8Skamil #endif
1680a0f774c8Skamil struct sigaction sa;
1681a0f774c8Skamil struct ptrace_siginfo info;
1682a0f774c8Skamil sigset_t intmask;
1683a0f774c8Skamil struct kinfo_proc2 kp;
1684a0f774c8Skamil size_t len = sizeof(kp);
1685a0f774c8Skamil
1686a0f774c8Skamil int name[6];
1687a0f774c8Skamil const size_t namelen = __arraycount(name);
1688a0f774c8Skamil ki_sigset_t kp_sigmask;
1689a0f774c8Skamil ki_sigset_t kp_sigignore;
1690a0f774c8Skamil
1691a0f774c8Skamil #ifndef PTRACE_ILLEGAL_ASM
1692a0f774c8Skamil if (sig == SIGILL)
1693a0f774c8Skamil atf_tc_skip("PTRACE_ILLEGAL_ASM not defined");
1694a0f774c8Skamil #endif
1695a0f774c8Skamil
1696a0f774c8Skamil if (sig == SIGFPE && !are_fpu_exceptions_supported())
1697a0f774c8Skamil atf_tc_skip("FP exceptions are not supported");
1698a0f774c8Skamil
1699a0f774c8Skamil memset(&info, 0, sizeof(info));
1700a0f774c8Skamil
1701a0f774c8Skamil DPRINTF("Spawn tracee\n");
1702a0f774c8Skamil SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
1703a0f774c8Skamil tracee = atf_utils_fork();
1704a0f774c8Skamil if (tracee == 0) {
1705a0f774c8Skamil // Wait for parent to let us crash
1706a0f774c8Skamil CHILD_FROM_PARENT("exit tracee", parent_tracee, msg);
1707a0f774c8Skamil
1708a0f774c8Skamil if (masked) {
1709a0f774c8Skamil sigemptyset(&intmask);
1710a0f774c8Skamil sigaddset(&intmask, sig);
1711a0f774c8Skamil sigprocmask(SIG_BLOCK, &intmask, NULL);
1712a0f774c8Skamil }
1713a0f774c8Skamil
1714a0f774c8Skamil if (ignored) {
1715a0f774c8Skamil memset(&sa, 0, sizeof(sa));
1716a0f774c8Skamil sa.sa_handler = SIG_IGN;
1717a0f774c8Skamil sigemptyset(&sa.sa_mask);
1718a0f774c8Skamil FORKEE_ASSERT(sigaction(sig, &sa, NULL) != -1);
1719a0f774c8Skamil }
1720a0f774c8Skamil
1721a0f774c8Skamil DPRINTF("Before raising %s from child\n", strsignal(sigval));
1722a0f774c8Skamil FORKEE_ASSERT(raise(sigval) == 0);
1723a0f774c8Skamil
1724a0f774c8Skamil DPRINTF("Before executing a trap\n");
1725a0f774c8Skamil switch (sig) {
1726a0f774c8Skamil case SIGTRAP:
1727a0f774c8Skamil trigger_trap();
1728a0f774c8Skamil break;
1729a0f774c8Skamil case SIGSEGV:
1730a0f774c8Skamil trigger_segv();
1731a0f774c8Skamil break;
1732a0f774c8Skamil case SIGILL:
1733a0f774c8Skamil trigger_ill();
1734a0f774c8Skamil break;
1735a0f774c8Skamil case SIGFPE:
1736a0f774c8Skamil trigger_fpe();
1737a0f774c8Skamil break;
1738a0f774c8Skamil case SIGBUS:
1739a0f774c8Skamil trigger_bus();
1740a0f774c8Skamil break;
1741a0f774c8Skamil default:
1742a0f774c8Skamil /* NOTREACHED */
1743a0f774c8Skamil FORKEE_ASSERTX(0 && "This shall not be reached");
1744a0f774c8Skamil }
1745a0f774c8Skamil
1746a0f774c8Skamil /* NOTREACHED */
1747a0f774c8Skamil FORKEE_ASSERTX(0 && "This shall not be reached");
1748a0f774c8Skamil }
1749a0f774c8Skamil
1750a0f774c8Skamil DPRINTF("Spawn debugger\n");
1751a0f774c8Skamil SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
1752a0f774c8Skamil tracer = atf_utils_fork();
1753a0f774c8Skamil if (tracer == 0) {
1754a0f774c8Skamil /* Fork again and drop parent to reattach to PID 1 */
1755a0f774c8Skamil tracer = atf_utils_fork();
1756a0f774c8Skamil if (tracer != 0)
1757a0f774c8Skamil _exit(exitval);
1758a0f774c8Skamil
1759a0f774c8Skamil DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
1760a0f774c8Skamil FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
1761a0f774c8Skamil
1762a0f774c8Skamil /* Wait for tracee and assert that it was stopped w/ SIGSTOP */
1763a0f774c8Skamil FORKEE_REQUIRE_SUCCESS(
1764a0f774c8Skamil wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
1765a0f774c8Skamil
1766a0f774c8Skamil forkee_status_stopped(status, SIGSTOP);
1767a0f774c8Skamil
1768a0f774c8Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for the "
1769a0f774c8Skamil "traced process\n");
1770a0f774c8Skamil SYSCALL_REQUIRE(
1771a0f774c8Skamil ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1);
1772a0f774c8Skamil
1773a0f774c8Skamil DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
1774a0f774c8Skamil DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
1775a0f774c8Skamil "si_errno=%#x\n", info.psi_siginfo.si_signo,
1776a0f774c8Skamil info.psi_siginfo.si_code, info.psi_siginfo.si_errno);
1777a0f774c8Skamil
1778a0f774c8Skamil FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, SIGSTOP);
1779a0f774c8Skamil FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_USER);
1780a0f774c8Skamil
1781a0f774c8Skamil /* Resume tracee with PT_CONTINUE */
1782a0f774c8Skamil FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
1783a0f774c8Skamil
1784a0f774c8Skamil /* Inform parent that tracer has attached to tracee */
1785a0f774c8Skamil CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
1786a0f774c8Skamil
1787a0f774c8Skamil /* Wait for parent to tell use that tracee should have exited */
1788a0f774c8Skamil CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg);
1789a0f774c8Skamil
1790a0f774c8Skamil /* Wait for tracee and assert that it exited */
1791a0f774c8Skamil FORKEE_REQUIRE_SUCCESS(
1792a0f774c8Skamil wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
1793a0f774c8Skamil
1794a0f774c8Skamil forkee_status_stopped(status, sigval);
1795a0f774c8Skamil
1796a0f774c8Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for the "
1797a0f774c8Skamil "traced process\n");
1798a0f774c8Skamil SYSCALL_REQUIRE(
1799a0f774c8Skamil ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1);
1800a0f774c8Skamil
1801a0f774c8Skamil DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
1802a0f774c8Skamil DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
1803a0f774c8Skamil "si_errno=%#x\n", info.psi_siginfo.si_signo,
1804a0f774c8Skamil info.psi_siginfo.si_code, info.psi_siginfo.si_errno);
1805a0f774c8Skamil
1806a0f774c8Skamil FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, sigval);
1807a0f774c8Skamil FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_LWP);
1808a0f774c8Skamil
1809a0f774c8Skamil name[0] = CTL_KERN,
1810a0f774c8Skamil name[1] = KERN_PROC2,
1811a0f774c8Skamil name[2] = KERN_PROC_PID;
1812a0f774c8Skamil name[3] = tracee;
1813a0f774c8Skamil name[4] = sizeof(kp);
1814a0f774c8Skamil name[5] = 1;
1815a0f774c8Skamil
1816a0f774c8Skamil FORKEE_ASSERT_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
1817a0f774c8Skamil
1818a0f774c8Skamil if (masked)
1819a0f774c8Skamil kp_sigmask = kp.p_sigmask;
1820a0f774c8Skamil
1821a0f774c8Skamil if (ignored)
1822a0f774c8Skamil kp_sigignore = kp.p_sigignore;
1823a0f774c8Skamil
1824a0f774c8Skamil /* Resume tracee with PT_CONTINUE */
1825a0f774c8Skamil FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
1826a0f774c8Skamil
1827a0f774c8Skamil /* Wait for tracee and assert that it exited */
1828a0f774c8Skamil FORKEE_REQUIRE_SUCCESS(
1829a0f774c8Skamil wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
1830a0f774c8Skamil
1831a0f774c8Skamil forkee_status_stopped(status, sig);
1832a0f774c8Skamil
1833a0f774c8Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for the "
1834a0f774c8Skamil "traced process\n");
1835a0f774c8Skamil SYSCALL_REQUIRE(
1836a0f774c8Skamil ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1);
1837a0f774c8Skamil
1838a0f774c8Skamil DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
1839a0f774c8Skamil DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
1840a0f774c8Skamil "si_errno=%#x\n", info.psi_siginfo.si_signo,
1841a0f774c8Skamil info.psi_siginfo.si_code, info.psi_siginfo.si_errno);
1842a0f774c8Skamil
1843a0f774c8Skamil FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, sig);
1844a0f774c8Skamil
1845a0f774c8Skamil FORKEE_ASSERT_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
1846a0f774c8Skamil
1847a0f774c8Skamil if (masked) {
1848a0f774c8Skamil DPRINTF("kp_sigmask="
1849a0f774c8Skamil "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
1850a0f774c8Skamil PRIx32 "\n",
1851a0f774c8Skamil kp_sigmask.__bits[0], kp_sigmask.__bits[1],
1852a0f774c8Skamil kp_sigmask.__bits[2], kp_sigmask.__bits[3]);
1853a0f774c8Skamil
1854a0f774c8Skamil DPRINTF("kp.p_sigmask="
1855a0f774c8Skamil "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
1856a0f774c8Skamil PRIx32 "\n",
1857a0f774c8Skamil kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1],
1858a0f774c8Skamil kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]);
1859a0f774c8Skamil
1860a0f774c8Skamil FORKEE_ASSERTX(!memcmp(&kp_sigmask, &kp.p_sigmask,
1861a0f774c8Skamil sizeof(kp_sigmask)));
1862a0f774c8Skamil }
1863a0f774c8Skamil
1864a0f774c8Skamil if (ignored) {
1865a0f774c8Skamil DPRINTF("kp_sigignore="
1866a0f774c8Skamil "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
1867a0f774c8Skamil PRIx32 "\n",
1868a0f774c8Skamil kp_sigignore.__bits[0], kp_sigignore.__bits[1],
1869a0f774c8Skamil kp_sigignore.__bits[2], kp_sigignore.__bits[3]);
1870a0f774c8Skamil
1871a0f774c8Skamil DPRINTF("kp.p_sigignore="
1872a0f774c8Skamil "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
1873a0f774c8Skamil PRIx32 "\n",
1874a0f774c8Skamil kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1],
1875a0f774c8Skamil kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]);
1876a0f774c8Skamil
1877a0f774c8Skamil FORKEE_ASSERTX(!memcmp(&kp_sigignore, &kp.p_sigignore,
1878a0f774c8Skamil sizeof(kp_sigignore)));
1879a0f774c8Skamil }
1880a0f774c8Skamil
1881a0f774c8Skamil switch (sig) {
1882a0f774c8Skamil case SIGTRAP:
1883a0f774c8Skamil FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, TRAP_BRKPT);
1884a0f774c8Skamil break;
1885a0f774c8Skamil case SIGSEGV:
1886a0f774c8Skamil FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SEGV_MAPERR);
1887a0f774c8Skamil break;
1888a0f774c8Skamil case SIGILL:
1889a0f774c8Skamil FORKEE_ASSERT(info.psi_siginfo.si_code >= ILL_ILLOPC &&
1890a0f774c8Skamil info.psi_siginfo.si_code <= ILL_BADSTK);
1891a0f774c8Skamil break;
1892a0f774c8Skamil case SIGFPE:
1893c3c8ab88Srin // XXXQEMU FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, FPE_FLTDIV);
1894a0f774c8Skamil break;
1895a0f774c8Skamil case SIGBUS:
1896a0f774c8Skamil FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, BUS_ADRERR);
1897a0f774c8Skamil break;
1898a0f774c8Skamil }
1899a0f774c8Skamil
1900a0f774c8Skamil FORKEE_ASSERT(ptrace(PT_KILL, tracee, NULL, 0) != -1);
1901a0f774c8Skamil DPRINTF("Before calling %s() for the tracee\n", TWAIT_FNAME);
1902a0f774c8Skamil FORKEE_REQUIRE_SUCCESS(
1903a0f774c8Skamil wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
1904a0f774c8Skamil
1905a0f774c8Skamil forkee_status_signaled(status, SIGKILL, 0);
1906a0f774c8Skamil
1907a0f774c8Skamil /* Inform parent that tracer is exiting normally */
1908a0f774c8Skamil CHILD_TO_PARENT("tracer done", parent_tracer, msg);
1909a0f774c8Skamil
1910a0f774c8Skamil DPRINTF("Before exiting of the tracer process\n");
1911a0f774c8Skamil _exit(0 /* collect by initproc */);
1912a0f774c8Skamil }
1913a0f774c8Skamil
1914a0f774c8Skamil DPRINTF("Wait for the tracer process (direct child) to exit "
1915a0f774c8Skamil "calling %s()\n", TWAIT_FNAME);
1916a0f774c8Skamil TWAIT_REQUIRE_SUCCESS(
1917a0f774c8Skamil wpid = TWAIT_GENERIC(tracer, &status, 0), tracer);
1918a0f774c8Skamil
1919a0f774c8Skamil validate_status_exited(status, exitval);
1920a0f774c8Skamil
1921a0f774c8Skamil DPRINTF("Wait for the non-exited tracee process with %s()\n",
1922a0f774c8Skamil TWAIT_FNAME);
1923a0f774c8Skamil TWAIT_REQUIRE_SUCCESS(
1924a0f774c8Skamil wpid = TWAIT_GENERIC(tracee, NULL, WNOHANG), 0);
1925a0f774c8Skamil
1926a0f774c8Skamil DPRINTF("Wait for the tracer to attach to the tracee\n");
1927a0f774c8Skamil PARENT_FROM_CHILD("tracer ready", parent_tracer, msg);
1928a0f774c8Skamil
1929a0f774c8Skamil DPRINTF("Resume the tracee and let it crash\n");
1930a0f774c8Skamil PARENT_TO_CHILD("exit tracee", parent_tracee, msg);
1931a0f774c8Skamil
1932a0f774c8Skamil DPRINTF("Resume the tracer and let it detect crashed tracee\n");
1933a0f774c8Skamil PARENT_TO_CHILD("Message 2", parent_tracer, msg);
1934a0f774c8Skamil
1935a0f774c8Skamil DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
1936a0f774c8Skamil TWAIT_FNAME);
1937a0f774c8Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
1938a0f774c8Skamil
1939a0f774c8Skamil validate_status_signaled(status, SIGKILL, 0);
1940a0f774c8Skamil
1941a0f774c8Skamil DPRINTF("Await normal exit of tracer\n");
1942a0f774c8Skamil PARENT_FROM_CHILD("tracer done", parent_tracer, msg);
1943a0f774c8Skamil
1944a0f774c8Skamil msg_close(&parent_tracer);
1945a0f774c8Skamil msg_close(&parent_tracee);
1946a0f774c8Skamil }
1947a0f774c8Skamil
1948a0f774c8Skamil #define UNRELATED_TRACER_SEES_CRASH(test, sig) \
1949a0f774c8Skamil ATF_TC(test); \
1950a0f774c8Skamil ATF_TC_HEAD(test, tc) \
1951a0f774c8Skamil { \
1952a0f774c8Skamil atf_tc_set_md_var(tc, "descr", \
1953a0f774c8Skamil "Assert that an unrelated tracer sees crash signal from " \
1954a0f774c8Skamil "the debuggee"); \
1955a0f774c8Skamil } \
1956a0f774c8Skamil \
1957a0f774c8Skamil ATF_TC_BODY(test, tc) \
1958a0f774c8Skamil { \
1959a0f774c8Skamil \
1960a0f774c8Skamil unrelated_tracer_sees_crash(sig, false, false); \
1961a0f774c8Skamil }
1962a0f774c8Skamil
1963a0f774c8Skamil UNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_trap, SIGTRAP)
1964a0f774c8Skamil UNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_segv, SIGSEGV)
1965a0f774c8Skamil UNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_ill, SIGILL)
1966a0f774c8Skamil UNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_fpe, SIGFPE)
1967a0f774c8Skamil UNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_bus, SIGBUS)
1968a0f774c8Skamil
1969a0f774c8Skamil #define UNRELATED_TRACER_SEES_SIGNALMASKED_CRASH(test, sig) \
1970a0f774c8Skamil ATF_TC(test); \
1971a0f774c8Skamil ATF_TC_HEAD(test, tc) \
1972a0f774c8Skamil { \
1973a0f774c8Skamil atf_tc_set_md_var(tc, "descr", \
1974a0f774c8Skamil "Assert that an unrelated tracer sees crash signal from " \
1975a0f774c8Skamil "the debuggee with masked signal"); \
1976a0f774c8Skamil } \
1977a0f774c8Skamil \
1978a0f774c8Skamil ATF_TC_BODY(test, tc) \
1979a0f774c8Skamil { \
1980a0f774c8Skamil \
1981a0f774c8Skamil unrelated_tracer_sees_crash(sig, true, false); \
1982a0f774c8Skamil }
1983a0f774c8Skamil
1984a0f774c8Skamil UNRELATED_TRACER_SEES_SIGNALMASKED_CRASH(
1985a0f774c8Skamil unrelated_tracer_sees_signalmasked_crash_trap, SIGTRAP)
1986a0f774c8Skamil UNRELATED_TRACER_SEES_SIGNALMASKED_CRASH(
1987a0f774c8Skamil unrelated_tracer_sees_signalmasked_crash_segv, SIGSEGV)
1988a0f774c8Skamil UNRELATED_TRACER_SEES_SIGNALMASKED_CRASH(
1989a0f774c8Skamil unrelated_tracer_sees_signalmasked_crash_ill, SIGILL)
1990a0f774c8Skamil UNRELATED_TRACER_SEES_SIGNALMASKED_CRASH(
1991a0f774c8Skamil unrelated_tracer_sees_signalmasked_crash_fpe, SIGFPE)
1992a0f774c8Skamil UNRELATED_TRACER_SEES_SIGNALMASKED_CRASH(
1993a0f774c8Skamil unrelated_tracer_sees_signalmasked_crash_bus, SIGBUS)
1994a0f774c8Skamil
1995a0f774c8Skamil #define UNRELATED_TRACER_SEES_SIGNALIGNORED_CRASH(test, sig) \
1996a0f774c8Skamil ATF_TC(test); \
1997a0f774c8Skamil ATF_TC_HEAD(test, tc) \
1998a0f774c8Skamil { \
1999a0f774c8Skamil atf_tc_set_md_var(tc, "descr", \
2000a0f774c8Skamil "Assert that an unrelated tracer sees crash signal from " \
2001a0f774c8Skamil "the debuggee with signal ignored"); \
2002a0f774c8Skamil } \
2003a0f774c8Skamil \
2004a0f774c8Skamil ATF_TC_BODY(test, tc) \
2005a0f774c8Skamil { \
2006a0f774c8Skamil \
2007a0f774c8Skamil unrelated_tracer_sees_crash(sig, false, true); \
2008a0f774c8Skamil }
2009a0f774c8Skamil
2010a0f774c8Skamil UNRELATED_TRACER_SEES_SIGNALIGNORED_CRASH(
2011a0f774c8Skamil unrelated_tracer_sees_signalignored_crash_trap, SIGTRAP)
2012a0f774c8Skamil UNRELATED_TRACER_SEES_SIGNALIGNORED_CRASH(
2013a0f774c8Skamil unrelated_tracer_sees_signalignored_crash_segv, SIGSEGV)
2014a0f774c8Skamil UNRELATED_TRACER_SEES_SIGNALIGNORED_CRASH(
2015a0f774c8Skamil unrelated_tracer_sees_signalignored_crash_ill, SIGILL)
2016a0f774c8Skamil UNRELATED_TRACER_SEES_SIGNALIGNORED_CRASH(
2017a0f774c8Skamil unrelated_tracer_sees_signalignored_crash_fpe, SIGFPE)
2018a0f774c8Skamil UNRELATED_TRACER_SEES_SIGNALIGNORED_CRASH(
2019a0f774c8Skamil unrelated_tracer_sees_signalignored_crash_bus, SIGBUS)
2020a0f774c8Skamil #endif
2021a0f774c8Skamil
2022a0f774c8Skamil /// ----------------------------------------------------------------------------
2023a0f774c8Skamil
2024a0f774c8Skamil ATF_TC(signal_mask_unrelated);
ATF_TC_HEAD(signal_mask_unrelated,tc)2025a0f774c8Skamil ATF_TC_HEAD(signal_mask_unrelated, tc)
2026a0f774c8Skamil {
2027a0f774c8Skamil atf_tc_set_md_var(tc, "descr",
2028a0f774c8Skamil "Verify that masking single unrelated signal does not stop tracer "
2029a0f774c8Skamil "from catching other signals");
2030a0f774c8Skamil }
2031a0f774c8Skamil
ATF_TC_BODY(signal_mask_unrelated,tc)2032a0f774c8Skamil ATF_TC_BODY(signal_mask_unrelated, tc)
2033a0f774c8Skamil {
2034a0f774c8Skamil const int exitval = 5;
2035a0f774c8Skamil const int sigval = SIGSTOP;
2036a0f774c8Skamil const int sigmasked = SIGTRAP;
2037a0f774c8Skamil const int signotmasked = SIGINT;
2038a0f774c8Skamil pid_t child, wpid;
2039a0f774c8Skamil #if defined(TWAIT_HAVE_STATUS)
2040a0f774c8Skamil int status;
2041a0f774c8Skamil #endif
2042a0f774c8Skamil sigset_t intmask;
2043a0f774c8Skamil
2044a0f774c8Skamil DPRINTF("Before forking process PID=%d\n", getpid());
2045a0f774c8Skamil SYSCALL_REQUIRE((child = fork()) != -1);
2046a0f774c8Skamil if (child == 0) {
2047a0f774c8Skamil DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
2048a0f774c8Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
2049a0f774c8Skamil
2050a0f774c8Skamil sigemptyset(&intmask);
2051a0f774c8Skamil sigaddset(&intmask, sigmasked);
2052a0f774c8Skamil sigprocmask(SIG_BLOCK, &intmask, NULL);
2053a0f774c8Skamil
2054a0f774c8Skamil DPRINTF("Before raising %s from child\n", strsignal(sigval));
2055a0f774c8Skamil FORKEE_ASSERT(raise(sigval) == 0);
2056a0f774c8Skamil
2057a0f774c8Skamil DPRINTF("Before raising %s from child\n",
2058a0f774c8Skamil strsignal(signotmasked));
2059a0f774c8Skamil FORKEE_ASSERT(raise(signotmasked) == 0);
2060a0f774c8Skamil
2061a0f774c8Skamil DPRINTF("Before exiting of the child process\n");
2062a0f774c8Skamil _exit(exitval);
2063a0f774c8Skamil }
2064a0f774c8Skamil DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
2065a0f774c8Skamil
2066a0f774c8Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2067a0f774c8Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2068a0f774c8Skamil
2069a0f774c8Skamil validate_status_stopped(status, sigval);
2070a0f774c8Skamil
2071a0f774c8Skamil DPRINTF("Before resuming the child process where it left off and "
2072a0f774c8Skamil "without signal to be sent\n");
2073a0f774c8Skamil SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
2074a0f774c8Skamil
2075a0f774c8Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2076a0f774c8Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2077a0f774c8Skamil
2078a0f774c8Skamil validate_status_stopped(status, signotmasked);
2079a0f774c8Skamil
2080a0f774c8Skamil DPRINTF("Before resuming the child process where it left off and "
2081a0f774c8Skamil "without signal to be sent\n");
2082a0f774c8Skamil SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
2083a0f774c8Skamil
2084a0f774c8Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2085a0f774c8Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2086a0f774c8Skamil
2087a0f774c8Skamil validate_status_exited(status, exitval);
2088a0f774c8Skamil
2089a0f774c8Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2090a0f774c8Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
2091a0f774c8Skamil }
2092a0f774c8Skamil
2093a0f774c8Skamil /// ----------------------------------------------------------------------------
2094a0f774c8Skamil
2095a0f774c8Skamil #define ATF_TP_ADD_TCS_PTRACE_WAIT_SIGNAL() \
2096a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_raise1); \
2097a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_raise2); \
2098a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_raise3); \
2099a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_raise4); \
2100a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_raise5); \
2101a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_raise6); \
2102a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_raise7); \
2103a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_raise8); \
2104a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_raise9); \
2105a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_raise10); \
2106a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored1); \
2107a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored2); \
2108a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored3); \
2109a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored4); \
2110a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored5); \
2111a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored6); \
2112a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored7); \
2113a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored8); \
2114a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_raisesignal_masked1); \
2115a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_raisesignal_masked2); \
2116a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_raisesignal_masked3); \
2117a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_raisesignal_masked4); \
2118a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_raisesignal_masked5); \
2119a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_raisesignal_masked6); \
2120a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_raisesignal_masked7); \
2121a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_raisesignal_masked8); \
2122a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_crash_trap); \
2123a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_crash_segv); \
2124a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_crash_ill); \
2125a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_crash_fpe); \
2126a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_crash_bus); \
2127a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_trap); \
2128a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_segv); \
2129a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_ill); \
2130a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_fpe); \
2131a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_bus); \
2132a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_signalignored_crash_trap); \
2133a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_signalignored_crash_segv); \
2134a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_signalignored_crash_ill); \
2135a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_signalignored_crash_fpe); \
2136a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_signalignored_crash_bus); \
2137a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_handle1); \
2138a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_handle2); \
2139a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_handle3); \
2140a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_handle4); \
2141a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_handle5); \
2142a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_handle6); \
2143a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_handle7); \
2144a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_handle8); \
2145a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_masked1); \
2146a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_masked2); \
2147a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_masked3); \
2148a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_masked4); \
2149a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_masked5); \
2150a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_masked6); \
2151a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_masked7); \
2152a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_masked8); \
2153a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored1); \
2154a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored2); \
2155a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored3); \
2156a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored4); \
2157a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored5); \
2158a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored6); \
2159a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored7); \
2160a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored8); \
2161a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_simple1); \
2162a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_simple2); \
2163a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_simple3); \
2164a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_simple4); \
2165a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_simple5); \
2166a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_simple6); \
2167a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_simple7); \
2168a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_simple8); \
2169a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_simple9); \
2170a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_simple10); \
2171a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_vfork_raise1); \
2172a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_vfork_raise2); \
2173a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_vfork_raise3); \
2174a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_vfork_raise4); \
2175a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_vfork_raise5); \
2176a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_vfork_raise6); \
2177a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_vfork_raise7); \
2178a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_vfork_raise8); \
2179a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_vfork_raise9); \
2180a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_vfork_raise10); \
2181a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_vfork_raise11); \
2182a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_vfork_raise12); \
2183a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_vfork_raise13); \
2184a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_vfork_crash_trap); \
2185a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_vfork_crash_segv); \
2186a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_vfork_crash_ill); \
2187a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_vfork_crash_fpe); \
2188a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_vfork_crash_bus); \
2189a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_trap); \
2190a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_segv); \
2191a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_ill); \
2192a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_fpe); \
2193a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_bus); \
2194a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_trap); \
2195a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_segv); \
2196a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_ill); \
2197a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_fpe); \
2198a0f774c8Skamil ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_bus); \
2199a0f774c8Skamil ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_trap); \
2200a0f774c8Skamil ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_segv); \
2201a0f774c8Skamil ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_ill); \
2202a0f774c8Skamil ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_fpe); \
2203a0f774c8Skamil ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_bus); \
2204a0f774c8Skamil ATF_TP_ADD_TC_HAVE_PID(tp, \
2205a0f774c8Skamil unrelated_tracer_sees_signalmasked_crash_trap); \
2206a0f774c8Skamil ATF_TP_ADD_TC_HAVE_PID(tp, \
2207a0f774c8Skamil unrelated_tracer_sees_signalmasked_crash_segv); \
2208a0f774c8Skamil ATF_TP_ADD_TC_HAVE_PID(tp, \
2209a0f774c8Skamil unrelated_tracer_sees_signalmasked_crash_ill); \
2210a0f774c8Skamil ATF_TP_ADD_TC_HAVE_PID(tp, \
2211a0f774c8Skamil unrelated_tracer_sees_signalmasked_crash_fpe); \
2212a0f774c8Skamil ATF_TP_ADD_TC_HAVE_PID(tp, \
2213a0f774c8Skamil unrelated_tracer_sees_signalmasked_crash_bus); \
2214a0f774c8Skamil ATF_TP_ADD_TC_HAVE_PID(tp, \
2215a0f774c8Skamil unrelated_tracer_sees_signalignored_crash_trap); \
2216a0f774c8Skamil ATF_TP_ADD_TC_HAVE_PID(tp, \
2217a0f774c8Skamil unrelated_tracer_sees_signalignored_crash_segv); \
2218a0f774c8Skamil ATF_TP_ADD_TC_HAVE_PID(tp, \
2219a0f774c8Skamil unrelated_tracer_sees_signalignored_crash_ill); \
2220a0f774c8Skamil ATF_TP_ADD_TC_HAVE_PID(tp, \
2221a0f774c8Skamil unrelated_tracer_sees_signalignored_crash_fpe); \
2222a0f774c8Skamil ATF_TP_ADD_TC_HAVE_PID(tp, \
2223a0f774c8Skamil unrelated_tracer_sees_signalignored_crash_bus); \
2224a0f774c8Skamil ATF_TP_ADD_TC(tp, signal_mask_unrelated);
2225