1 /* $NetBSD: t_ptrace_wait.c,v 1.69 2017/01/27 16:43:07 kamil Exp $ */
2
3 /*-
4 * Copyright (c) 2016 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #include <sys/cdefs.h>
30 __RCSID("$NetBSD: t_ptrace_wait.c,v 1.69 2017/01/27 16:43:07 kamil Exp $");
31
32 #include <sys/param.h>
33 #include <sys/types.h>
34 #include <sys/ptrace.h>
35 #include <sys/resource.h>
36 #include <sys/stat.h>
37 #include <sys/sysctl.h>
38 #include <sys/wait.h>
39 #include <machine/reg.h>
40 #include <elf.h>
41 #include <err.h>
42 #include <errno.h>
43 #include <lwp.h>
44 #include <signal.h>
45 #include <stdint.h>
46 #include <stdio.h>
47 #include <stdlib.h>
48 #include <strings.h>
49 #include <unistd.h>
50
51 #include <atf-c.h>
52
53 #include "h_macros.h"
54
55 #include "t_ptrace_wait.h"
56 #include "msg.h"
57
58 #define PARENT_TO_CHILD(info, fds, msg) \
59 ATF_REQUIRE(msg_write_child(info " to child " # fds, &fds, &msg, sizeof(msg)) == 0)
60
61 #define CHILD_FROM_PARENT(info, fds, msg) \
62 FORKEE_ASSERT(msg_read_parent(info " from parent " # fds, &fds, &msg, sizeof(msg)) == 0)
63
64 #define CHILD_TO_PARENT(info, fds, msg) \
65 FORKEE_ASSERT(msg_write_parent(info " to parent " # fds, &fds, &msg, sizeof(msg)) == 0)
66
67 #define PARENT_FROM_CHILD(info, fds, msg) \
68 ATF_REQUIRE(msg_read_child(info " from parent " # fds, &fds, &msg, sizeof(msg)) == 0)
69
70
71 ATF_TC(traceme1);
ATF_TC_HEAD(traceme1,tc)72 ATF_TC_HEAD(traceme1, tc)
73 {
74 atf_tc_set_md_var(tc, "descr",
75 "Verify SIGSTOP followed by _exit(2) in a child");
76 }
77
ATF_TC_BODY(traceme1,tc)78 ATF_TC_BODY(traceme1, tc)
79 {
80 const int exitval = 5;
81 const int sigval = SIGSTOP;
82 pid_t child, wpid;
83 #if defined(TWAIT_HAVE_STATUS)
84 int status;
85 #endif
86
87 printf("Before forking process PID=%d\n", getpid());
88 ATF_REQUIRE((child = fork()) != -1);
89 if (child == 0) {
90 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
91 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
92
93 printf("Before raising %s from child\n", strsignal(sigval));
94 FORKEE_ASSERT(raise(sigval) == 0);
95
96 printf("Before exiting of the child process\n");
97 _exit(exitval);
98 }
99 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
100
101 printf("Before calling %s() for the child\n", TWAIT_FNAME);
102 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
103
104 validate_status_stopped(status, sigval);
105
106 printf("Before resuming the child process where it left off and "
107 "without signal to be sent\n");
108 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
109
110 printf("Before calling %s() for the child\n", TWAIT_FNAME);
111 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
112
113 validate_status_exited(status, exitval);
114
115 printf("Before calling %s() for the child\n", TWAIT_FNAME);
116 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
117 }
118
119 ATF_TC(traceme2);
ATF_TC_HEAD(traceme2,tc)120 ATF_TC_HEAD(traceme2, tc)
121 {
122 atf_tc_set_md_var(tc, "descr",
123 "Verify SIGSTOP followed by _exit(2) in a child");
124 }
125
126 static int traceme2_caught = 0;
127
128 static void
traceme2_sighandler(int sig)129 traceme2_sighandler(int sig)
130 {
131 FORKEE_ASSERT_EQ(sig, SIGINT);
132
133 ++traceme2_caught;
134 }
135
ATF_TC_BODY(traceme2,tc)136 ATF_TC_BODY(traceme2, tc)
137 {
138 const int exitval = 5;
139 const int sigval = SIGSTOP, sigsent = SIGINT;
140 pid_t child, wpid;
141 struct sigaction sa;
142 #if defined(TWAIT_HAVE_STATUS)
143 int status;
144 #endif
145
146 printf("Before forking process PID=%d\n", getpid());
147 ATF_REQUIRE((child = fork()) != -1);
148 if (child == 0) {
149 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
150 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
151
152 sa.sa_handler = traceme2_sighandler;
153 sa.sa_flags = SA_SIGINFO;
154 sigemptyset(&sa.sa_mask);
155
156 FORKEE_ASSERT(sigaction(sigsent, &sa, NULL) != -1);
157
158 printf("Before raising %s from child\n", strsignal(sigval));
159 FORKEE_ASSERT(raise(sigval) == 0);
160
161 FORKEE_ASSERT_EQ(traceme2_caught, 1);
162
163 printf("Before exiting of the child process\n");
164 _exit(exitval);
165 }
166 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
167
168 printf("Before calling %s() for the child\n", TWAIT_FNAME);
169 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
170
171 validate_status_stopped(status, sigval);
172
173 printf("Before resuming the child process where it left off and with "
174 "signal %s to be sent\n", strsignal(sigsent));
175 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1);
176
177 printf("Before calling %s() for the child\n", TWAIT_FNAME);
178 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
179
180 validate_status_exited(status, exitval);
181
182 printf("Before calling %s() for the exited child\n", TWAIT_FNAME);
183 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
184 }
185
186 ATF_TC(traceme3);
ATF_TC_HEAD(traceme3,tc)187 ATF_TC_HEAD(traceme3, tc)
188 {
189 atf_tc_set_md_var(tc, "descr",
190 "Verify SIGSTOP followed by termination by a signal in a child");
191 }
192
ATF_TC_BODY(traceme3,tc)193 ATF_TC_BODY(traceme3, tc)
194 {
195 const int sigval = SIGSTOP, sigsent = SIGINT /* Without core-dump */;
196 pid_t child, wpid;
197 #if defined(TWAIT_HAVE_STATUS)
198 int status;
199 #endif
200
201 printf("Before forking process PID=%d\n", getpid());
202 ATF_REQUIRE((child = fork()) != -1);
203 if (child == 0) {
204 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
205 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
206
207 printf("Before raising %s from child\n", strsignal(sigval));
208 FORKEE_ASSERT(raise(sigval) == 0);
209
210 /* NOTREACHED */
211 FORKEE_ASSERTX(0 &&
212 "Child should be terminated by a signal from its parent");
213 }
214 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
215
216 printf("Before calling %s() for the child\n", TWAIT_FNAME);
217 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
218
219 validate_status_stopped(status, sigval);
220
221 printf("Before resuming the child process where it left off and with "
222 "signal %s to be sent\n", strsignal(sigsent));
223 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1);
224
225 printf("Before calling %s() for the child\n", TWAIT_FNAME);
226 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
227
228 validate_status_signaled(status, sigsent, 0);
229
230 printf("Before calling %s() for the exited child\n", TWAIT_FNAME);
231 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
232 }
233
234 ATF_TC(traceme4);
ATF_TC_HEAD(traceme4,tc)235 ATF_TC_HEAD(traceme4, tc)
236 {
237 atf_tc_set_md_var(tc, "descr",
238 "Verify SIGSTOP followed by SIGCONT and _exit(2) in a child");
239 }
240
ATF_TC_BODY(traceme4,tc)241 ATF_TC_BODY(traceme4, tc)
242 {
243 const int exitval = 5;
244 const int sigval = SIGSTOP, sigsent = SIGCONT;
245 pid_t child, wpid;
246 #if defined(TWAIT_HAVE_STATUS)
247 int status;
248 #endif
249
250 printf("Before forking process PID=%d\n", getpid());
251 ATF_REQUIRE((child = fork()) != -1);
252 if (child == 0) {
253 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
254 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
255
256 printf("Before raising %s from child\n", strsignal(sigval));
257 FORKEE_ASSERT(raise(sigval) == 0);
258
259 printf("Before raising %s from child\n", strsignal(sigsent));
260 FORKEE_ASSERT(raise(sigsent) == 0);
261
262 printf("Before exiting of the child process\n");
263 _exit(exitval);
264 }
265 printf("Parent process PID=%d, child's PID=%d\n", getpid(),child);
266
267 printf("Before calling %s() for the child\n", TWAIT_FNAME);
268 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
269
270 validate_status_stopped(status, sigval);
271
272 printf("Before resuming the child process where it left off and "
273 "without signal to be sent\n");
274 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
275
276 printf("Before calling %s() for the child\n", TWAIT_FNAME);
277 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
278
279 validate_status_stopped(status, sigsent);
280
281 printf("Before resuming the child process where it left off and "
282 "without signal to be sent\n");
283 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
284
285 printf("Before calling %s() for the child\n", TWAIT_FNAME);
286 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
287
288 validate_status_exited(status, exitval);
289
290 printf("Before calling %s() for the exited child\n", TWAIT_FNAME);
291 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
292 }
293
294 #if defined(TWAIT_HAVE_PID)
295 ATF_TC(attach1);
ATF_TC_HEAD(attach1,tc)296 ATF_TC_HEAD(attach1, tc)
297 {
298 atf_tc_set_md_var(tc, "descr",
299 "Assert that tracer sees process termination before the parent");
300 }
301
ATF_TC_BODY(attach1,tc)302 ATF_TC_BODY(attach1, tc)
303 {
304 struct msg_fds parent_tracee, parent_tracer;
305 const int exitval_tracee = 5;
306 const int exitval_tracer = 10;
307 pid_t tracee, tracer, wpid;
308 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
309 #if defined(TWAIT_HAVE_STATUS)
310 int status;
311 #endif
312
313 printf("Spawn tracee\n");
314 ATF_REQUIRE(msg_open(&parent_tracee) == 0);
315 tracee = atf_utils_fork();
316 if (tracee == 0) {
317 // Wait for parent to let us exit
318 CHILD_FROM_PARENT("exit tracee", parent_tracee, msg);
319 _exit(exitval_tracee);
320 }
321
322 printf("Spawn debugger\n");
323 ATF_REQUIRE(msg_open(&parent_tracer) == 0);
324 tracer = atf_utils_fork();
325 if (tracer == 0) {
326 printf("Before calling PT_ATTACH from tracee %d\n", getpid());
327 FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
328
329 /* Wait for tracee and assert that it was stopped w/ SIGSTOP */
330 FORKEE_REQUIRE_SUCCESS(
331 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
332
333 forkee_status_stopped(status, SIGSTOP);
334
335 /* Resume tracee with PT_CONTINUE */
336 FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
337
338 /* Inform parent that tracer has attached to tracee */
339 CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
340
341 /* Wait for parent to tell use that tracee should have exited */
342 CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg);
343
344 /* Wait for tracee and assert that it exited */
345 FORKEE_REQUIRE_SUCCESS(
346 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
347
348 forkee_status_exited(status, exitval_tracee);
349 printf("Tracee %d exited with %d\n", tracee, exitval_tracee);
350
351 printf("Before exiting of the tracer process\n");
352 _exit(exitval_tracer);
353 }
354
355 printf("Wait for the tracer to attach to the tracee\n");
356 PARENT_FROM_CHILD("tracer ready", parent_tracer, msg);
357
358 printf("Resume the tracee and let it exit\n");
359 PARENT_TO_CHILD("exit tracee", parent_tracee, msg);
360
361 printf("Detect that tracee is zombie\n");
362 await_zombie(tracee);
363
364
365 printf("Assert that there is no status about tracee %d - "
366 "Tracer must detect zombie first - calling %s()\n", tracee,
367 TWAIT_FNAME);
368 TWAIT_REQUIRE_SUCCESS(
369 wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
370
371 printf("Tell the tracer child should have exited\n");
372 PARENT_TO_CHILD("wait for tracee exit", parent_tracer, msg);
373 printf("Wait for tracer to finish its job and exit - calling %s()\n",
374 TWAIT_FNAME);
375
376 printf("Wait from tracer child to complete waiting for tracee\n");
377 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
378 tracer);
379
380 validate_status_exited(status, exitval_tracer);
381
382 printf("Wait for tracee to finish its job and exit - calling %s()\n",
383 TWAIT_FNAME);
384 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
385 tracee);
386
387 validate_status_exited(status, exitval_tracee);
388
389 msg_close(&parent_tracer);
390 msg_close(&parent_tracee);
391 }
392 #endif
393
394 #if defined(TWAIT_HAVE_PID)
395 ATF_TC(attach2);
ATF_TC_HEAD(attach2,tc)396 ATF_TC_HEAD(attach2, tc)
397 {
398 atf_tc_set_md_var(tc, "descr",
399 "Assert that any tracer sees process termination before its "
400 "parent");
401 }
402
ATF_TC_BODY(attach2,tc)403 ATF_TC_BODY(attach2, tc)
404 {
405 struct msg_fds parent_tracer, parent_tracee;
406 const int exitval_tracee = 5;
407 const int exitval_tracer1 = 10, exitval_tracer2 = 20;
408 pid_t tracee, tracer, wpid;
409 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
410 #if defined(TWAIT_HAVE_STATUS)
411 int status;
412 #endif
413
414 printf("Spawn tracee\n");
415 ATF_REQUIRE(msg_open(&parent_tracee) == 0);
416 tracee = atf_utils_fork();
417 if (tracee == 0) {
418 /* Wait for message from the parent */
419 CHILD_FROM_PARENT("Message 1", parent_tracee, msg);
420 _exit(exitval_tracee);
421 }
422
423 printf("Spawn debugger\n");
424 ATF_REQUIRE(msg_open(&parent_tracer) == 0);
425 tracer = atf_utils_fork();
426 if (tracer == 0) {
427 /* Fork again and drop parent to reattach to PID 1 */
428 tracer = atf_utils_fork();
429 if (tracer != 0)
430 _exit(exitval_tracer1);
431
432 printf("Before calling PT_ATTACH from tracee %d\n", getpid());
433 FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
434
435 /* Wait for tracee and assert that it was stopped w/ SIGSTOP */
436 FORKEE_REQUIRE_SUCCESS(
437 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
438
439 forkee_status_stopped(status, SIGSTOP);
440
441 /* Resume tracee with PT_CONTINUE */
442 FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
443
444 /* Inform parent that tracer has attached to tracee */
445 CHILD_TO_PARENT("Message 1", parent_tracer, msg);
446 CHILD_FROM_PARENT("Message 2", parent_tracer, msg);
447
448 /* Wait for tracee and assert that it exited */
449 FORKEE_REQUIRE_SUCCESS(
450 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
451
452 forkee_status_exited(status, exitval_tracee);
453
454 printf("Before exiting of the tracer process\n");
455 _exit(exitval_tracer2);
456 }
457 printf("Wait for the tracer process (direct child) to exit calling "
458 "%s()\n", TWAIT_FNAME);
459 TWAIT_REQUIRE_SUCCESS(
460 wpid = TWAIT_GENERIC(tracer, &status, 0), tracer);
461
462 validate_status_exited(status, exitval_tracer1);
463
464 printf("Wait for the non-exited tracee process with %s()\n",
465 TWAIT_FNAME);
466 TWAIT_REQUIRE_SUCCESS(
467 wpid = TWAIT_GENERIC(tracee, NULL, WNOHANG), 0);
468
469 printf("Wait for the tracer to attach to the tracee\n");
470 PARENT_FROM_CHILD("Message 1", parent_tracer, msg);
471 printf("Resume the tracee and let it exit\n");
472 PARENT_TO_CHILD("Message 1", parent_tracee, msg);
473
474 printf("Detect that tracee is zombie\n");
475 await_zombie(tracee);
476
477 printf("Assert that there is no status about tracee - "
478 "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
479 TWAIT_REQUIRE_SUCCESS(
480 wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
481
482 printf("Resume the tracer and let it detect exited tracee\n");
483 PARENT_TO_CHILD("Message 2", parent_tracer, msg);
484
485 printf("Wait for tracee to finish its job and exit - calling %s()\n",
486 TWAIT_FNAME);
487 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
488 tracee);
489
490 validate_status_exited(status, exitval_tracee);
491
492 msg_close(&parent_tracer);
493 msg_close(&parent_tracee);
494
495 }
496 #endif
497
498 ATF_TC(attach3);
ATF_TC_HEAD(attach3,tc)499 ATF_TC_HEAD(attach3, tc)
500 {
501 atf_tc_set_md_var(tc, "descr",
502 "Assert that tracer parent can PT_ATTACH to its child");
503 }
504
ATF_TC_BODY(attach3,tc)505 ATF_TC_BODY(attach3, tc)
506 {
507 struct msg_fds parent_tracee;
508 const int exitval_tracee = 5;
509 pid_t tracee, wpid;
510 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
511 #if defined(TWAIT_HAVE_STATUS)
512 int status;
513 #endif
514
515 printf("Spawn tracee\n");
516 ATF_REQUIRE(msg_open(&parent_tracee) == 0);
517 tracee = atf_utils_fork();
518 if (tracee == 0) {
519 CHILD_FROM_PARENT("Message 1", parent_tracee, msg);
520 printf("Parent should now attach to tracee\n");
521
522 CHILD_FROM_PARENT("Message 2", parent_tracee, msg);
523 /* Wait for message from the parent */
524 _exit(exitval_tracee);
525 }
526 PARENT_TO_CHILD("Message 1", parent_tracee, msg);
527
528 printf("Before calling PT_ATTACH for tracee %d\n", tracee);
529 ATF_REQUIRE(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
530
531 printf("Wait for the stopped tracee process with %s()\n",
532 TWAIT_FNAME);
533 TWAIT_REQUIRE_SUCCESS(
534 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
535
536 validate_status_stopped(status, SIGSTOP);
537
538 printf("Resume tracee with PT_CONTINUE\n");
539 ATF_REQUIRE(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
540
541 printf("Let the tracee exit now\n");
542 PARENT_TO_CHILD("Message 2", parent_tracee, msg);
543
544 printf("Wait for tracee to exit with %s()\n", TWAIT_FNAME);
545 TWAIT_REQUIRE_SUCCESS(
546 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
547
548 validate_status_exited(status, exitval_tracee);
549
550 printf("Before calling %s() for tracee\n", TWAIT_FNAME);
551 TWAIT_REQUIRE_FAILURE(ECHILD,
552 wpid = TWAIT_GENERIC(tracee, &status, 0));
553
554 msg_close(&parent_tracee);
555 }
556
557 ATF_TC(attach4);
ATF_TC_HEAD(attach4,tc)558 ATF_TC_HEAD(attach4, tc)
559 {
560 atf_tc_set_md_var(tc, "descr",
561 "Assert that tracer child can PT_ATTACH to its parent");
562 }
563
ATF_TC_BODY(attach4,tc)564 ATF_TC_BODY(attach4, tc)
565 {
566 struct msg_fds parent_tracee;
567 const int exitval_tracer = 5;
568 pid_t tracer, wpid;
569 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
570 #if defined(TWAIT_HAVE_STATUS)
571 int status;
572 #endif
573
574 printf("Spawn tracer\n");
575 ATF_REQUIRE(msg_open(&parent_tracee) == 0);
576 tracer = atf_utils_fork();
577 if (tracer == 0) {
578
579 /* Wait for message from the parent */
580 CHILD_FROM_PARENT("Message 1", parent_tracee, msg);
581
582 printf("Attach to parent PID %d with PT_ATTACH from child\n",
583 getppid());
584 FORKEE_ASSERT(ptrace(PT_ATTACH, getppid(), NULL, 0) != -1);
585
586 printf("Wait for the stopped parent process with %s()\n",
587 TWAIT_FNAME);
588 FORKEE_REQUIRE_SUCCESS(
589 wpid = TWAIT_GENERIC(getppid(), &status, 0), getppid());
590
591 forkee_status_stopped(status, SIGSTOP);
592
593 printf("Resume parent with PT_DETACH\n");
594 FORKEE_ASSERT(ptrace(PT_DETACH, getppid(), (void *)1, 0)
595 != -1);
596
597 /* Tell parent we are ready */
598 CHILD_TO_PARENT("Message 1", parent_tracee, msg);
599
600 _exit(exitval_tracer);
601 }
602
603 printf("Wait for the tracer to become ready\n");
604 PARENT_TO_CHILD("Message 1", parent_tracee, msg);
605 printf("Allow the tracer to exit now\n");
606 PARENT_FROM_CHILD("Message 1", parent_tracee, msg);
607
608 printf("Wait for tracer to exit with %s()\n", TWAIT_FNAME);
609 TWAIT_REQUIRE_SUCCESS(
610 wpid = TWAIT_GENERIC(tracer, &status, 0), tracer);
611
612 validate_status_exited(status, exitval_tracer);
613
614 printf("Before calling %s() for tracer\n", TWAIT_FNAME);
615 TWAIT_REQUIRE_FAILURE(ECHILD,
616 wpid = TWAIT_GENERIC(tracer, &status, 0));
617
618 msg_close(&parent_tracee);
619 }
620
621 #if defined(TWAIT_HAVE_PID)
622 ATF_TC(attach5);
ATF_TC_HEAD(attach5,tc)623 ATF_TC_HEAD(attach5, tc)
624 {
625 atf_tc_set_md_var(tc, "descr",
626 "Assert that tracer sees its parent when attached to tracer "
627 "(check getppid(2))");
628 }
629
ATF_TC_BODY(attach5,tc)630 ATF_TC_BODY(attach5, tc)
631 {
632 struct msg_fds parent_tracer, parent_tracee;
633 const int exitval_tracee = 5;
634 const int exitval_tracer = 10;
635 pid_t parent, tracee, tracer, wpid;
636 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
637 #if defined(TWAIT_HAVE_STATUS)
638 int status;
639 #endif
640
641 printf("Spawn tracee\n");
642 ATF_REQUIRE(msg_open(&parent_tracer) == 0);
643 ATF_REQUIRE(msg_open(&parent_tracee) == 0);
644 tracee = atf_utils_fork();
645 if (tracee == 0) {
646 parent = getppid();
647
648 /* Emit message to the parent */
649 CHILD_TO_PARENT("tracee ready", parent_tracee, msg);
650 CHILD_FROM_PARENT("exit tracee", parent_tracee, msg);
651
652 FORKEE_ASSERT_EQ(parent, getppid());
653
654 _exit(exitval_tracee);
655 }
656 printf("Wait for child to record its parent identifier (pid)\n");
657 PARENT_FROM_CHILD("tracee ready", parent_tracee, msg);
658
659 printf("Spawn debugger\n");
660 tracer = atf_utils_fork();
661 if (tracer == 0) {
662 /* No IPC to communicate with the child */
663 printf("Before calling PT_ATTACH from tracee %d\n", getpid());
664 FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
665
666 /* Wait for tracee and assert that it was stopped w/ SIGSTOP */
667 FORKEE_REQUIRE_SUCCESS(
668 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
669
670 forkee_status_stopped(status, SIGSTOP);
671
672 /* Resume tracee with PT_CONTINUE */
673 FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
674
675 /* Inform parent that tracer has attached to tracee */
676 CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
677
678 /* Wait for parent to tell use that tracee should have exited */
679 CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg);
680
681 /* Wait for tracee and assert that it exited */
682 FORKEE_REQUIRE_SUCCESS(
683 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
684
685 forkee_status_exited(status, exitval_tracee);
686
687 printf("Before exiting of the tracer process\n");
688 _exit(exitval_tracer);
689 }
690
691 printf("Wait for the tracer to attach to the tracee\n");
692 PARENT_FROM_CHILD("tracer ready", parent_tracer, msg);
693
694 printf("Resume the tracee and let it exit\n");
695 PARENT_TO_CHILD("exit tracee", parent_tracee, msg);
696
697 printf("Detect that tracee is zombie\n");
698 await_zombie(tracee);
699
700 printf("Assert that there is no status about tracee - "
701 "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
702 TWAIT_REQUIRE_SUCCESS(
703 wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
704
705 printf("Tell the tracer child should have exited\n");
706 PARENT_TO_CHILD("wait for tracee exit", parent_tracer, msg);
707
708 printf("Wait from tracer child to complete waiting for tracee\n");
709 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
710 tracer);
711
712 validate_status_exited(status, exitval_tracer);
713
714 printf("Wait for tracee to finish its job and exit - calling %s()\n",
715 TWAIT_FNAME);
716 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
717 tracee);
718
719 validate_status_exited(status, exitval_tracee);
720
721 msg_close(&parent_tracer);
722 msg_close(&parent_tracee);
723 }
724 #endif
725
726 #if defined(TWAIT_HAVE_PID)
727 ATF_TC(attach6);
ATF_TC_HEAD(attach6,tc)728 ATF_TC_HEAD(attach6, tc)
729 {
730 atf_tc_set_md_var(tc, "descr",
731 "Assert that tracer sees its parent when attached to tracer "
732 "(check sysctl(7) and struct kinfo_proc2)");
733 }
734
ATF_TC_BODY(attach6,tc)735 ATF_TC_BODY(attach6, tc)
736 {
737 struct msg_fds parent_tracee, parent_tracer;
738 const int exitval_tracee = 5;
739 const int exitval_tracer = 10;
740 pid_t parent, tracee, tracer, wpid;
741 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
742 #if defined(TWAIT_HAVE_STATUS)
743 int status;
744 #endif
745 int name[CTL_MAXNAME];
746 struct kinfo_proc2 kp;
747 size_t len = sizeof(kp);
748 unsigned int namelen;
749
750 printf("Spawn tracee\n");
751 ATF_REQUIRE(msg_open(&parent_tracee) == 0);
752 ATF_REQUIRE(msg_open(&parent_tracer) == 0);
753 tracee = atf_utils_fork();
754 if (tracee == 0) {
755 parent = getppid();
756
757 /* Emit message to the parent */
758 CHILD_TO_PARENT("Message 1", parent_tracee, msg);
759 CHILD_FROM_PARENT("Message 2", parent_tracee, msg);
760
761 namelen = 0;
762 name[namelen++] = CTL_KERN;
763 name[namelen++] = KERN_PROC2;
764 name[namelen++] = KERN_PROC_PID;
765 name[namelen++] = getpid();
766 name[namelen++] = len;
767 name[namelen++] = 1;
768
769 FORKEE_ASSERT(sysctl(name, namelen, &kp, &len, NULL, 0) == 0);
770 FORKEE_ASSERT_EQ(parent, kp.p_ppid);
771
772 _exit(exitval_tracee);
773 }
774
775 printf("Wait for child to record its parent identifier (pid)\n");
776 PARENT_FROM_CHILD("Message 1", parent_tracee, msg);
777
778 printf("Spawn debugger\n");
779 tracer = atf_utils_fork();
780 if (tracer == 0) {
781 /* No IPC to communicate with the child */
782 printf("Before calling PT_ATTACH from tracee %d\n", getpid());
783 FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
784
785 /* Wait for tracee and assert that it was stopped w/ SIGSTOP */
786 FORKEE_REQUIRE_SUCCESS(
787 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
788
789 forkee_status_stopped(status, SIGSTOP);
790
791 /* Resume tracee with PT_CONTINUE */
792 FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
793
794 /* Inform parent that tracer has attached to tracee */
795 CHILD_TO_PARENT("Message 1", parent_tracer, msg);
796
797 CHILD_FROM_PARENT("Message 2", parent_tracer, msg);
798
799 /* Wait for tracee and assert that it exited */
800 FORKEE_REQUIRE_SUCCESS(
801 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
802
803 forkee_status_exited(status, exitval_tracee);
804
805 printf("Before exiting of the tracer process\n");
806 _exit(exitval_tracer);
807 }
808
809 printf("Wait for the tracer to attach to the tracee\n");
810 PARENT_FROM_CHILD("Message 1", parent_tracer, msg);
811
812 printf("Resume the tracee and let it exit\n");
813 PARENT_TO_CHILD("Message 1", parent_tracee, msg);
814
815 printf("Detect that tracee is zombie\n");
816 await_zombie(tracee);
817
818 printf("Assert that there is no status about tracee - "
819 "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
820 TWAIT_REQUIRE_SUCCESS(
821 wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
822
823 printf("Resume the tracer and let it detect exited tracee\n");
824 PARENT_TO_CHILD("Message 2", parent_tracer, msg);
825
826 printf("Wait for tracer to finish its job and exit - calling %s()\n",
827 TWAIT_FNAME);
828 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
829 tracer);
830
831 validate_status_exited(status, exitval_tracer);
832
833 printf("Wait for tracee to finish its job and exit - calling %s()\n",
834 TWAIT_FNAME);
835 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
836 tracee);
837
838 validate_status_exited(status, exitval_tracee);
839
840 msg_close(&parent_tracee);
841 msg_close(&parent_tracer);
842 }
843 #endif
844
845 #if defined(TWAIT_HAVE_PID)
846 ATF_TC(attach7);
ATF_TC_HEAD(attach7,tc)847 ATF_TC_HEAD(attach7, tc)
848 {
849 atf_tc_set_md_var(tc, "descr",
850 "Assert that tracer sees its parent when attached to tracer "
851 "(check /proc/curproc/status 3rd column)");
852 }
853
ATF_TC_BODY(attach7,tc)854 ATF_TC_BODY(attach7, tc)
855 {
856 struct msg_fds parent_tracee, parent_tracer;
857 int rv;
858 const int exitval_tracee = 5;
859 const int exitval_tracer = 10;
860 pid_t parent, tracee, tracer, wpid;
861 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
862 #if defined(TWAIT_HAVE_STATUS)
863 int status;
864 #endif
865 FILE *fp;
866 struct stat st;
867 const char *fname = "/proc/curproc/status";
868 char s_executable[MAXPATHLEN];
869 int s_pid, s_ppid;
870 /*
871 * Format:
872 * EXECUTABLE PID PPID ...
873 */
874
875 ATF_REQUIRE((rv = stat(fname, &st)) == 0 || (errno == ENOENT));
876 if (rv != 0) {
877 atf_tc_skip("/proc/curproc/status not found");
878 }
879
880 printf("Spawn tracee\n");
881 ATF_REQUIRE(msg_open(&parent_tracee) == 0);
882 ATF_REQUIRE(msg_open(&parent_tracer) == 0);
883 tracee = atf_utils_fork();
884 if (tracee == 0) {
885 parent = getppid();
886
887 // Wait for parent to let us exit
888 CHILD_TO_PARENT("tracee ready", parent_tracee, msg);
889 CHILD_FROM_PARENT("tracee exit", parent_tracee, msg);
890
891 FORKEE_ASSERT((fp = fopen(fname, "r")) != NULL);
892 fscanf(fp, "%s %d %d", s_executable, &s_pid, &s_ppid);
893 FORKEE_ASSERT(fclose(fp) == 0);
894 FORKEE_ASSERT_EQ(parent, s_ppid);
895
896 _exit(exitval_tracee);
897 }
898
899 printf("Wait for child to record its parent identifier (pid)\n");
900 PARENT_FROM_CHILD("tracee ready", parent_tracee, msg);
901
902 printf("Spawn debugger\n");
903 tracer = atf_utils_fork();
904 if (tracer == 0) {
905 printf("Before calling PT_ATTACH from tracee %d\n", getpid());
906 FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
907
908 /* Wait for tracee and assert that it was stopped w/ SIGSTOP */
909 FORKEE_REQUIRE_SUCCESS(
910 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
911
912 forkee_status_stopped(status, SIGSTOP);
913
914 /* Resume tracee with PT_CONTINUE */
915 FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
916
917 /* Inform parent that tracer has attached to tracee */
918 CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
919
920 /* Wait for parent to tell use that tracee should have exited */
921 CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg);
922
923 /* Wait for tracee and assert that it exited */
924 FORKEE_REQUIRE_SUCCESS(
925 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
926
927 forkee_status_exited(status, exitval_tracee);
928
929 printf("Before exiting of the tracer process\n");
930 _exit(exitval_tracer);
931 }
932 printf("Wait for the tracer to attach to the tracee\n");
933 PARENT_FROM_CHILD("tracer ready", parent_tracer, msg);
934 printf("Resume the tracee and let it exit\n");
935 PARENT_TO_CHILD("tracee exit", parent_tracee, msg);
936
937 printf("Detect that tracee is zombie\n");
938 await_zombie(tracee);
939
940 printf("Assert that there is no status about tracee - "
941 "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
942 TWAIT_REQUIRE_SUCCESS(
943 wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
944
945 printf("Resume the tracer and let it detect exited tracee\n");
946 PARENT_TO_CHILD("Message 2", parent_tracer, msg);
947
948 printf("Wait for tracer to finish its job and exit - calling %s()\n",
949 TWAIT_FNAME);
950 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
951 tracer);
952
953 validate_status_exited(status, exitval_tracer);
954
955 printf("Wait for tracee to finish its job and exit - calling %s()\n",
956 TWAIT_FNAME);
957 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
958 tracee);
959
960 validate_status_exited(status, exitval_tracee);
961
962 msg_close(&parent_tracee);
963 msg_close(&parent_tracer);
964 }
965 #endif
966
967 ATF_TC(eventmask1);
ATF_TC_HEAD(eventmask1,tc)968 ATF_TC_HEAD(eventmask1, tc)
969 {
970 atf_tc_set_md_var(tc, "descr",
971 "Verify that empty EVENT_MASK is preserved");
972 }
973
ATF_TC_BODY(eventmask1,tc)974 ATF_TC_BODY(eventmask1, tc)
975 {
976 const int exitval = 5;
977 const int sigval = SIGSTOP;
978 pid_t child, wpid;
979 #if defined(TWAIT_HAVE_STATUS)
980 int status;
981 #endif
982 ptrace_event_t set_event, get_event;
983 const int len = sizeof(ptrace_event_t);
984
985 printf("Before forking process PID=%d\n", getpid());
986 ATF_REQUIRE((child = fork()) != -1);
987 if (child == 0) {
988 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
989 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
990
991 printf("Before raising %s from child\n", strsignal(sigval));
992 FORKEE_ASSERT(raise(sigval) == 0);
993
994 printf("Before exiting of the child process\n");
995 _exit(exitval);
996 }
997 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
998
999 printf("Before calling %s() for the child\n", TWAIT_FNAME);
1000 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1001
1002 validate_status_stopped(status, sigval);
1003
1004 set_event.pe_set_event = 0;
1005 ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
1006 ATF_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
1007 ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
1008
1009 printf("Before resuming the child process where it left off and "
1010 "without signal to be sent\n");
1011 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1012
1013 printf("Before calling %s() for the child\n", TWAIT_FNAME);
1014 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1015
1016 validate_status_exited(status, exitval);
1017
1018 printf("Before calling %s() for the child\n", TWAIT_FNAME);
1019 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1020 }
1021
1022 ATF_TC(eventmask2);
ATF_TC_HEAD(eventmask2,tc)1023 ATF_TC_HEAD(eventmask2, tc)
1024 {
1025 atf_tc_set_md_var(tc, "descr",
1026 "Verify that PTRACE_FORK in EVENT_MASK is preserved");
1027 }
1028
ATF_TC_BODY(eventmask2,tc)1029 ATF_TC_BODY(eventmask2, tc)
1030 {
1031 const int exitval = 5;
1032 const int sigval = SIGSTOP;
1033 pid_t child, wpid;
1034 #if defined(TWAIT_HAVE_STATUS)
1035 int status;
1036 #endif
1037 ptrace_event_t set_event, get_event;
1038 const int len = sizeof(ptrace_event_t);
1039
1040 printf("Before forking process PID=%d\n", getpid());
1041 ATF_REQUIRE((child = fork()) != -1);
1042 if (child == 0) {
1043 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
1044 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1045
1046 printf("Before raising %s from child\n", strsignal(sigval));
1047 FORKEE_ASSERT(raise(sigval) == 0);
1048
1049 printf("Before exiting of the child process\n");
1050 _exit(exitval);
1051 }
1052 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1053
1054 printf("Before calling %s() for the child\n", TWAIT_FNAME);
1055 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1056
1057 validate_status_stopped(status, sigval);
1058
1059 set_event.pe_set_event = PTRACE_FORK;
1060 ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
1061 ATF_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
1062 ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
1063
1064 printf("Before resuming the child process where it left off and "
1065 "without signal to be sent\n");
1066 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1067
1068 printf("Before calling %s() for the child\n", TWAIT_FNAME);
1069 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1070
1071 validate_status_exited(status, exitval);
1072
1073 printf("Before calling %s() for the child\n", TWAIT_FNAME);
1074 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1075 }
1076
1077 ATF_TC(eventmask3);
ATF_TC_HEAD(eventmask3,tc)1078 ATF_TC_HEAD(eventmask3, tc)
1079 {
1080 atf_tc_set_md_var(tc, "descr",
1081 "Verify that PTRACE_VFORK in EVENT_MASK is preserved");
1082 }
1083
ATF_TC_BODY(eventmask3,tc)1084 ATF_TC_BODY(eventmask3, tc)
1085 {
1086 const int exitval = 5;
1087 const int sigval = SIGSTOP;
1088 pid_t child, wpid;
1089 #if defined(TWAIT_HAVE_STATUS)
1090 int status;
1091 #endif
1092 ptrace_event_t set_event, get_event;
1093 const int len = sizeof(ptrace_event_t);
1094
1095 atf_tc_expect_fail("PR kern/51630");
1096
1097 printf("Before forking process PID=%d\n", getpid());
1098 ATF_REQUIRE((child = fork()) != -1);
1099 if (child == 0) {
1100 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
1101 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1102
1103 printf("Before raising %s from child\n", strsignal(sigval));
1104 FORKEE_ASSERT(raise(sigval) == 0);
1105
1106 printf("Before exiting of the child process\n");
1107 _exit(exitval);
1108 }
1109 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1110
1111 printf("Before calling %s() for the child\n", TWAIT_FNAME);
1112 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1113
1114 validate_status_stopped(status, sigval);
1115
1116 set_event.pe_set_event = PTRACE_VFORK;
1117 ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
1118 ATF_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
1119 ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
1120
1121 printf("Before resuming the child process where it left off and "
1122 "without signal to be sent\n");
1123 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1124
1125 printf("Before calling %s() for the child\n", TWAIT_FNAME);
1126 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1127
1128 validate_status_exited(status, exitval);
1129
1130 printf("Before calling %s() for the child\n", TWAIT_FNAME);
1131 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1132 }
1133
1134 ATF_TC(eventmask4);
ATF_TC_HEAD(eventmask4,tc)1135 ATF_TC_HEAD(eventmask4, tc)
1136 {
1137 atf_tc_set_md_var(tc, "descr",
1138 "Verify that PTRACE_VFORK_DONE in EVENT_MASK is preserved");
1139 }
1140
ATF_TC_BODY(eventmask4,tc)1141 ATF_TC_BODY(eventmask4, tc)
1142 {
1143 const int exitval = 5;
1144 const int sigval = SIGSTOP;
1145 pid_t child, wpid;
1146 #if defined(TWAIT_HAVE_STATUS)
1147 int status;
1148 #endif
1149 ptrace_event_t set_event, get_event;
1150 const int len = sizeof(ptrace_event_t);
1151
1152 printf("Before forking process PID=%d\n", getpid());
1153 ATF_REQUIRE((child = fork()) != -1);
1154 if (child == 0) {
1155 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
1156 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1157
1158 printf("Before raising %s from child\n", strsignal(sigval));
1159 FORKEE_ASSERT(raise(sigval) == 0);
1160
1161 printf("Before exiting of the child process\n");
1162 _exit(exitval);
1163 }
1164 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1165
1166 printf("Before calling %s() for the child\n", TWAIT_FNAME);
1167 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1168
1169 validate_status_stopped(status, sigval);
1170
1171 set_event.pe_set_event = PTRACE_VFORK_DONE;
1172 ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
1173 ATF_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
1174 ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
1175
1176 printf("Before resuming the child process where it left off and "
1177 "without signal to be sent\n");
1178 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1179
1180 printf("Before calling %s() for the child\n", TWAIT_FNAME);
1181 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1182
1183 validate_status_exited(status, exitval);
1184
1185 printf("Before calling %s() for the child\n", TWAIT_FNAME);
1186 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1187 }
1188
1189 ATF_TC(eventmask5);
ATF_TC_HEAD(eventmask5,tc)1190 ATF_TC_HEAD(eventmask5, tc)
1191 {
1192 atf_tc_set_md_var(tc, "descr",
1193 "Verify that PTRACE_LWP_CREATE in EVENT_MASK is preserved");
1194 }
1195
ATF_TC_BODY(eventmask5,tc)1196 ATF_TC_BODY(eventmask5, tc)
1197 {
1198 const int exitval = 5;
1199 const int sigval = SIGSTOP;
1200 pid_t child, wpid;
1201 #if defined(TWAIT_HAVE_STATUS)
1202 int status;
1203 #endif
1204 ptrace_event_t set_event, get_event;
1205 const int len = sizeof(ptrace_event_t);
1206
1207 printf("Before forking process PID=%d\n", getpid());
1208 ATF_REQUIRE((child = fork()) != -1);
1209 if (child == 0) {
1210 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
1211 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1212
1213 printf("Before raising %s from child\n", strsignal(sigval));
1214 FORKEE_ASSERT(raise(sigval) == 0);
1215
1216 printf("Before exiting of the child process\n");
1217 _exit(exitval);
1218 }
1219 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1220
1221 printf("Before calling %s() for the child\n", TWAIT_FNAME);
1222 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1223
1224 validate_status_stopped(status, sigval);
1225
1226 set_event.pe_set_event = PTRACE_LWP_CREATE;
1227 ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
1228 ATF_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
1229 ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
1230
1231 printf("Before resuming the child process where it left off and "
1232 "without signal to be sent\n");
1233 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1234
1235 printf("Before calling %s() for the child\n", TWAIT_FNAME);
1236 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1237
1238 validate_status_exited(status, exitval);
1239
1240 printf("Before calling %s() for the child\n", TWAIT_FNAME);
1241 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1242 }
1243
1244 ATF_TC(eventmask6);
ATF_TC_HEAD(eventmask6,tc)1245 ATF_TC_HEAD(eventmask6, tc)
1246 {
1247 atf_tc_set_md_var(tc, "descr",
1248 "Verify that PTRACE_LWP_EXIT in EVENT_MASK is preserved");
1249 }
1250
ATF_TC_BODY(eventmask6,tc)1251 ATF_TC_BODY(eventmask6, tc)
1252 {
1253 const int exitval = 5;
1254 const int sigval = SIGSTOP;
1255 pid_t child, wpid;
1256 #if defined(TWAIT_HAVE_STATUS)
1257 int status;
1258 #endif
1259 ptrace_event_t set_event, get_event;
1260 const int len = sizeof(ptrace_event_t);
1261
1262 printf("Before forking process PID=%d\n", getpid());
1263 ATF_REQUIRE((child = fork()) != -1);
1264 if (child == 0) {
1265 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
1266 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1267
1268 printf("Before raising %s from child\n", strsignal(sigval));
1269 FORKEE_ASSERT(raise(sigval) == 0);
1270
1271 printf("Before exiting of the child process\n");
1272 _exit(exitval);
1273 }
1274 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1275
1276 printf("Before calling %s() for the child\n", TWAIT_FNAME);
1277 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1278
1279 validate_status_stopped(status, sigval);
1280
1281 set_event.pe_set_event = PTRACE_LWP_EXIT;
1282 ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
1283 ATF_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
1284 ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
1285
1286 printf("Before resuming the child process where it left off and "
1287 "without signal to be sent\n");
1288 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1289
1290 printf("Before calling %s() for the child\n", TWAIT_FNAME);
1291 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1292
1293 validate_status_exited(status, exitval);
1294
1295 printf("Before calling %s() for the child\n", TWAIT_FNAME);
1296 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1297 }
1298
1299 #if defined(TWAIT_HAVE_PID)
1300 ATF_TC(fork1);
ATF_TC_HEAD(fork1,tc)1301 ATF_TC_HEAD(fork1, tc)
1302 {
1303 atf_tc_set_md_var(tc, "descr",
1304 "Verify that fork(2) is intercepted by ptrace(2) with EVENT_MASK "
1305 "set to PTRACE_FORK");
1306 }
1307
ATF_TC_BODY(fork1,tc)1308 ATF_TC_BODY(fork1, tc)
1309 {
1310 const int exitval = 5;
1311 const int exitval2 = 15;
1312 const int sigval = SIGSTOP;
1313 pid_t child, child2, wpid;
1314 #if defined(TWAIT_HAVE_STATUS)
1315 int status;
1316 #endif
1317 ptrace_state_t state;
1318 const int slen = sizeof(state);
1319 ptrace_event_t event;
1320 const int elen = sizeof(event);
1321
1322 printf("Before forking process PID=%d\n", getpid());
1323 ATF_REQUIRE((child = fork()) != -1);
1324 if (child == 0) {
1325 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
1326 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1327
1328 printf("Before raising %s from child\n", strsignal(sigval));
1329 FORKEE_ASSERT(raise(sigval) == 0);
1330
1331 FORKEE_ASSERT((child2 = fork()) != 1);
1332
1333 if (child2 == 0)
1334 _exit(exitval2);
1335
1336 FORKEE_REQUIRE_SUCCESS
1337 (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
1338
1339 forkee_status_exited(status, exitval2);
1340
1341 printf("Before exiting of the child process\n");
1342 _exit(exitval);
1343 }
1344 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1345
1346 printf("Before calling %s() for the child\n", TWAIT_FNAME);
1347 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1348
1349 validate_status_stopped(status, sigval);
1350
1351 printf("Enable PTRACE_FORK in EVENT_MASK for the child %d\n", child);
1352 event.pe_set_event = PTRACE_FORK;
1353 ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
1354
1355 printf("Before resuming the child process where it left off and "
1356 "without signal to be sent\n");
1357 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1358
1359 printf("Before calling %s() for the child %d\n", TWAIT_FNAME, child);
1360 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1361
1362 validate_status_stopped(status, SIGTRAP);
1363
1364 ATF_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
1365 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
1366
1367 child2 = state.pe_other_pid;
1368 printf("Reported PTRACE_FORK event with forkee %d\n", child2);
1369
1370 printf("Before calling %s() for the forkee %d of the child %d\n",
1371 TWAIT_FNAME, child2, child);
1372 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
1373 child2);
1374
1375 validate_status_stopped(status, SIGTRAP);
1376
1377 ATF_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
1378 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
1379 ATF_REQUIRE_EQ(state.pe_other_pid, child);
1380
1381 printf("Before resuming the forkee process where it left off and "
1382 "without signal to be sent\n");
1383 ATF_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
1384
1385 printf("Before resuming the child process where it left off and "
1386 "without signal to be sent\n");
1387 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1388
1389 printf("Before calling %s() for the forkee - expected exited\n",
1390 TWAIT_FNAME);
1391 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
1392 child2);
1393
1394 validate_status_exited(status, exitval2);
1395
1396 printf("Before calling %s() for the forkee - expected no process\n",
1397 TWAIT_FNAME);
1398 TWAIT_REQUIRE_FAILURE(ECHILD,
1399 wpid = TWAIT_GENERIC(child2, &status, 0));
1400
1401 printf("Before calling %s() for the child - expected stopped "
1402 "SIGCHLD\n", TWAIT_FNAME);
1403 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1404
1405 validate_status_stopped(status, SIGCHLD);
1406
1407 printf("Before resuming the child process where it left off and "
1408 "without signal to be sent\n");
1409 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1410
1411 printf("Before calling %s() for the child - expected exited\n",
1412 TWAIT_FNAME);
1413 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1414
1415 validate_status_exited(status, exitval);
1416
1417 printf("Before calling %s() for the child - expected no process\n",
1418 TWAIT_FNAME);
1419 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1420 }
1421 #endif
1422
1423 ATF_TC(fork2);
ATF_TC_HEAD(fork2,tc)1424 ATF_TC_HEAD(fork2, tc)
1425 {
1426 atf_tc_set_md_var(tc, "descr",
1427 "Verify that fork(2) is not intercepted by ptrace(2) with empty "
1428 "EVENT_MASK");
1429 }
1430
ATF_TC_BODY(fork2,tc)1431 ATF_TC_BODY(fork2, tc)
1432 {
1433 const int exitval = 5;
1434 const int exitval2 = 15;
1435 const int sigval = SIGSTOP;
1436 pid_t child, child2, wpid;
1437 #if defined(TWAIT_HAVE_STATUS)
1438 int status;
1439 #endif
1440 ptrace_event_t event;
1441 const int elen = sizeof(event);
1442
1443 printf("Before forking process PID=%d\n", getpid());
1444 ATF_REQUIRE((child = fork()) != -1);
1445 if (child == 0) {
1446 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
1447 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1448
1449 printf("Before raising %s from child\n", strsignal(sigval));
1450 FORKEE_ASSERT(raise(sigval) == 0);
1451
1452 FORKEE_ASSERT((child2 = fork()) != 1);
1453
1454 if (child2 == 0)
1455 _exit(exitval2);
1456
1457 FORKEE_REQUIRE_SUCCESS
1458 (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
1459
1460 forkee_status_exited(status, exitval2);
1461
1462 printf("Before exiting of the child process\n");
1463 _exit(exitval);
1464 }
1465 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1466
1467 printf("Before calling %s() for the child\n", TWAIT_FNAME);
1468 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1469
1470 validate_status_stopped(status, sigval);
1471
1472 printf("Set empty EVENT_MASK for the child %d\n", child);
1473 event.pe_set_event = 0;
1474 ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
1475
1476 printf("Before resuming the child process where it left off and "
1477 "without signal to be sent\n");
1478 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1479
1480 printf("Before calling %s() for the child - expected stopped "
1481 "SIGCHLD\n", TWAIT_FNAME);
1482 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1483
1484 validate_status_stopped(status, SIGCHLD);
1485
1486 printf("Before resuming the child process where it left off and "
1487 "without signal to be sent\n");
1488 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1489
1490 printf("Before calling %s() for the child - expected exited\n",
1491 TWAIT_FNAME);
1492 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1493
1494 validate_status_exited(status, exitval);
1495
1496 printf("Before calling %s() for the child - expected no process\n",
1497 TWAIT_FNAME);
1498 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1499 }
1500
1501 #if defined(TWAIT_HAVE_PID)
1502 ATF_TC(vfork1);
ATF_TC_HEAD(vfork1,tc)1503 ATF_TC_HEAD(vfork1, tc)
1504 {
1505 atf_tc_set_md_var(tc, "descr",
1506 "Verify that vfork(2) is intercepted by ptrace(2) with EVENT_MASK "
1507 "set to PTRACE_VFORK");
1508 }
1509
ATF_TC_BODY(vfork1,tc)1510 ATF_TC_BODY(vfork1, tc)
1511 {
1512 const int exitval = 5;
1513 const int exitval2 = 15;
1514 const int sigval = SIGSTOP;
1515 pid_t child, child2, wpid;
1516 #if defined(TWAIT_HAVE_STATUS)
1517 int status;
1518 #endif
1519 ptrace_state_t state;
1520 const int slen = sizeof(state);
1521 ptrace_event_t event;
1522 const int elen = sizeof(event);
1523
1524 atf_tc_expect_fail("PR kern/51630");
1525
1526 printf("Before forking process PID=%d\n", getpid());
1527 ATF_REQUIRE((child = fork()) != -1);
1528 if (child == 0) {
1529 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
1530 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1531
1532 printf("Before raising %s from child\n", strsignal(sigval));
1533 FORKEE_ASSERT(raise(sigval) == 0);
1534
1535 FORKEE_ASSERT((child2 = vfork()) != 1);
1536
1537 if (child2 == 0)
1538 _exit(exitval2);
1539
1540 FORKEE_REQUIRE_SUCCESS
1541 (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
1542
1543 forkee_status_exited(status, exitval2);
1544
1545 printf("Before exiting of the child process\n");
1546 _exit(exitval);
1547 }
1548 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1549
1550 printf("Before calling %s() for the child\n", TWAIT_FNAME);
1551 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1552
1553 validate_status_stopped(status, sigval);
1554
1555 printf("Enable PTRACE_VFORK in EVENT_MASK for the child %d\n", child);
1556 event.pe_set_event = PTRACE_VFORK;
1557 ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
1558
1559 printf("Before resuming the child process where it left off and "
1560 "without signal to be sent\n");
1561 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1562
1563 printf("Before calling %s() for the child %d\n", TWAIT_FNAME, child);
1564 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1565
1566 validate_status_stopped(status, SIGTRAP);
1567
1568 ATF_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
1569 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK);
1570
1571 child2 = state.pe_other_pid;
1572 printf("Reported PTRACE_VFORK event with forkee %d\n", child2);
1573
1574 printf("Before calling %s() for the forkee %d of the child %d\n",
1575 TWAIT_FNAME, child2, child);
1576 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
1577 child2);
1578
1579 validate_status_stopped(status, SIGTRAP);
1580
1581 ATF_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
1582 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK);
1583 ATF_REQUIRE_EQ(state.pe_other_pid, child);
1584
1585 printf("Before resuming the forkee process where it left off and "
1586 "without signal to be sent\n");
1587 ATF_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
1588
1589 printf("Before resuming the child process where it left off and "
1590 "without signal to be sent\n");
1591 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1592
1593 printf("Before calling %s() for the forkee - expected exited\n",
1594 TWAIT_FNAME);
1595 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
1596 child2);
1597
1598 validate_status_exited(status, exitval2);
1599
1600 printf("Before calling %s() for the forkee - expected no process\n",
1601 TWAIT_FNAME);
1602 TWAIT_REQUIRE_FAILURE(ECHILD,
1603 wpid = TWAIT_GENERIC(child2, &status, 0));
1604
1605 printf("Before calling %s() for the child - expected stopped "
1606 "SIGCHLD\n", TWAIT_FNAME);
1607 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1608
1609 validate_status_stopped(status, SIGCHLD);
1610
1611 printf("Before resuming the child process where it left off and "
1612 "without signal to be sent\n");
1613 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1614
1615 printf("Before calling %s() for the child - expected exited\n",
1616 TWAIT_FNAME);
1617 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1618
1619 validate_status_exited(status, exitval);
1620
1621 printf("Before calling %s() for the child - expected no process\n",
1622 TWAIT_FNAME);
1623 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1624 }
1625 #endif
1626
1627 ATF_TC(vfork2);
ATF_TC_HEAD(vfork2,tc)1628 ATF_TC_HEAD(vfork2, tc)
1629 {
1630 atf_tc_set_md_var(tc, "descr",
1631 "Verify that vfork(2) is not intercepted by ptrace(2) with empty "
1632 "EVENT_MASK");
1633 }
1634
ATF_TC_BODY(vfork2,tc)1635 ATF_TC_BODY(vfork2, tc)
1636 {
1637 const int exitval = 5;
1638 const int exitval2 = 15;
1639 const int sigval = SIGSTOP;
1640 pid_t child, child2, wpid;
1641 #if defined(TWAIT_HAVE_STATUS)
1642 int status;
1643 #endif
1644 ptrace_event_t event;
1645 const int elen = sizeof(event);
1646
1647 printf("Before forking process PID=%d\n", getpid());
1648 ATF_REQUIRE((child = fork()) != -1);
1649 if (child == 0) {
1650 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
1651 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1652
1653 printf("Before raising %s from child\n", strsignal(sigval));
1654 FORKEE_ASSERT(raise(sigval) == 0);
1655
1656 FORKEE_ASSERT((child2 = vfork()) != 1);
1657
1658 if (child2 == 0)
1659 _exit(exitval2);
1660
1661 FORKEE_REQUIRE_SUCCESS
1662 (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
1663
1664 forkee_status_exited(status, exitval2);
1665
1666 printf("Before exiting of the child process\n");
1667 _exit(exitval);
1668 }
1669 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1670
1671 printf("Before calling %s() for the child\n", TWAIT_FNAME);
1672 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1673
1674 validate_status_stopped(status, sigval);
1675
1676 printf("Set empty EVENT_MASK for the child %d\n", child);
1677 event.pe_set_event = 0;
1678 ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
1679
1680 printf("Before resuming the child process where it left off and "
1681 "without signal to be sent\n");
1682 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1683
1684 printf("Before calling %s() for the child - expected stopped "
1685 "SIGCHLD\n", TWAIT_FNAME);
1686 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1687
1688 validate_status_stopped(status, SIGCHLD);
1689
1690 printf("Before resuming the child process where it left off and "
1691 "without signal to be sent\n");
1692 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1693
1694 printf("Before calling %s() for the child - expected exited\n",
1695 TWAIT_FNAME);
1696 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1697
1698 validate_status_exited(status, exitval);
1699
1700 printf("Before calling %s() for the child - expected no process\n",
1701 TWAIT_FNAME);
1702 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1703 }
1704
1705 ATF_TC(vforkdone1);
ATF_TC_HEAD(vforkdone1,tc)1706 ATF_TC_HEAD(vforkdone1, tc)
1707 {
1708 atf_tc_set_md_var(tc, "descr",
1709 "Verify that vfork(2) is intercepted by ptrace(2) with EVENT_MASK "
1710 "set to PTRACE_VFORK_DONE");
1711 }
1712
ATF_TC_BODY(vforkdone1,tc)1713 ATF_TC_BODY(vforkdone1, tc)
1714 {
1715 const int exitval = 5;
1716 const int exitval2 = 15;
1717 const int sigval = SIGSTOP;
1718 pid_t child, child2, wpid;
1719 #if defined(TWAIT_HAVE_STATUS)
1720 int status;
1721 #endif
1722 ptrace_state_t state;
1723 const int slen = sizeof(state);
1724 ptrace_event_t event;
1725 const int elen = sizeof(event);
1726
1727 printf("Before forking process PID=%d\n", getpid());
1728 ATF_REQUIRE((child = fork()) != -1);
1729 if (child == 0) {
1730 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
1731 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1732
1733 printf("Before raising %s from child\n", strsignal(sigval));
1734 FORKEE_ASSERT(raise(sigval) == 0);
1735
1736 FORKEE_ASSERT((child2 = vfork()) != 1);
1737
1738 if (child2 == 0)
1739 _exit(exitval2);
1740
1741 FORKEE_REQUIRE_SUCCESS
1742 (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
1743
1744 forkee_status_exited(status, exitval2);
1745
1746 printf("Before exiting of the child process\n");
1747 _exit(exitval);
1748 }
1749 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1750
1751 printf("Before calling %s() for the child\n", TWAIT_FNAME);
1752 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1753
1754 validate_status_stopped(status, sigval);
1755
1756 printf("Enable PTRACE_VFORK_DONE in EVENT_MASK for the child %d\n",
1757 child);
1758 event.pe_set_event = PTRACE_VFORK_DONE;
1759 ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
1760
1761 printf("Before resuming the child process where it left off and "
1762 "without signal to be sent\n");
1763 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1764
1765 printf("Before calling %s() for the child %d\n", TWAIT_FNAME, child);
1766 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1767
1768 validate_status_stopped(status, SIGTRAP);
1769
1770 ATF_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
1771 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE);
1772
1773 child2 = state.pe_other_pid;
1774 printf("Reported PTRACE_VFORK_DONE event with forkee %d\n", child2);
1775
1776 printf("Before resuming the child process where it left off and "
1777 "without signal to be sent\n");
1778 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1779
1780 printf("Before calling %s() for the child - expected stopped "
1781 "SIGCHLD\n", TWAIT_FNAME);
1782 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1783
1784 validate_status_stopped(status, SIGCHLD);
1785
1786 printf("Before resuming the child process where it left off and "
1787 "without signal to be sent\n");
1788 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1789
1790 printf("Before calling %s() for the child - expected exited\n",
1791 TWAIT_FNAME);
1792 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1793
1794 validate_status_exited(status, exitval);
1795
1796 printf("Before calling %s() for the child - expected no process\n",
1797 TWAIT_FNAME);
1798 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1799 }
1800
1801 ATF_TC(vforkdone2);
ATF_TC_HEAD(vforkdone2,tc)1802 ATF_TC_HEAD(vforkdone2, tc)
1803 {
1804 atf_tc_set_md_var(tc, "descr",
1805 "Verify that vfork(2) is intercepted by ptrace(2) with EVENT_MASK "
1806 "set to PTRACE_FORK | PTRACE_VFORK_DONE");
1807 }
1808
ATF_TC_BODY(vforkdone2,tc)1809 ATF_TC_BODY(vforkdone2, tc)
1810 {
1811 const int exitval = 5;
1812 const int exitval2 = 15;
1813 const int sigval = SIGSTOP;
1814 pid_t child, child2, wpid;
1815 #if defined(TWAIT_HAVE_STATUS)
1816 int status;
1817 #endif
1818 ptrace_state_t state;
1819 const int slen = sizeof(state);
1820 ptrace_event_t event;
1821 const int elen = sizeof(event);
1822
1823 printf("Before forking process PID=%d\n", getpid());
1824 ATF_REQUIRE((child = fork()) != -1);
1825 if (child == 0) {
1826 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
1827 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1828
1829 printf("Before raising %s from child\n", strsignal(sigval));
1830 FORKEE_ASSERT(raise(sigval) == 0);
1831
1832 FORKEE_ASSERT((child2 = vfork()) != 1);
1833
1834 if (child2 == 0)
1835 _exit(exitval2);
1836
1837 FORKEE_REQUIRE_SUCCESS
1838 (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
1839
1840 forkee_status_exited(status, exitval2);
1841
1842 printf("Before exiting of the child process\n");
1843 _exit(exitval);
1844 }
1845 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1846
1847 printf("Before calling %s() for the child\n", TWAIT_FNAME);
1848 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1849
1850 validate_status_stopped(status, sigval);
1851
1852 printf("Enable PTRACE_VFORK in EVENT_MASK for the child %d\n", child);
1853 event.pe_set_event = PTRACE_FORK | PTRACE_VFORK_DONE;
1854 ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
1855
1856 printf("Before resuming the child process where it left off and "
1857 "without signal to be sent\n");
1858 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1859
1860 printf("Before calling %s() for the child %d\n", TWAIT_FNAME, child);
1861 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1862
1863 validate_status_stopped(status, SIGTRAP);
1864
1865 ATF_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
1866 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE);
1867
1868 child2 = state.pe_other_pid;
1869 printf("Reported PTRACE_VFORK_DONE event with forkee %d\n", child2);
1870
1871 printf("Before resuming the child process where it left off and "
1872 "without signal to be sent\n");
1873 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1874
1875 printf("Before calling %s() for the child - expected stopped "
1876 "SIGCHLD\n", TWAIT_FNAME);
1877 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1878
1879 validate_status_stopped(status, SIGCHLD);
1880
1881 printf("Before resuming the child process where it left off and "
1882 "without signal to be sent\n");
1883 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1884
1885 printf("Before calling %s() for the child - expected exited\n",
1886 TWAIT_FNAME);
1887 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1888
1889 validate_status_exited(status, exitval);
1890
1891 printf("Before calling %s() for the child - expected no process\n",
1892 TWAIT_FNAME);
1893 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1894 }
1895
1896 ATF_TC(io_read_d1);
ATF_TC_HEAD(io_read_d1,tc)1897 ATF_TC_HEAD(io_read_d1, tc)
1898 {
1899 atf_tc_set_md_var(tc, "descr",
1900 "Verify PT_IO with PIOD_READ_D and len = sizeof(uint8_t)");
1901 }
1902
ATF_TC_BODY(io_read_d1,tc)1903 ATF_TC_BODY(io_read_d1, tc)
1904 {
1905 const int exitval = 5;
1906 const int sigval = SIGSTOP;
1907 pid_t child, wpid;
1908 uint8_t lookup_me = 0;
1909 const uint8_t magic = 0xab;
1910 struct ptrace_io_desc io = {
1911 .piod_op = PIOD_READ_D,
1912 .piod_offs = &lookup_me,
1913 .piod_addr = &lookup_me,
1914 .piod_len = sizeof(lookup_me)
1915 };
1916 #if defined(TWAIT_HAVE_STATUS)
1917 int status;
1918 #endif
1919
1920 printf("Before forking process PID=%d\n", getpid());
1921 ATF_REQUIRE((child = fork()) != -1);
1922 if (child == 0) {
1923 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
1924 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1925
1926 lookup_me = magic;
1927
1928 printf("Before raising %s from child\n", strsignal(sigval));
1929 FORKEE_ASSERT(raise(sigval) == 0);
1930
1931 printf("Before exiting of the child process\n");
1932 _exit(exitval);
1933 }
1934 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1935
1936 printf("Before calling %s() for the child\n", TWAIT_FNAME);
1937 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1938
1939 validate_status_stopped(status, sigval);
1940
1941 printf("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
1942 child, getpid());
1943 ATF_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
1944
1945 ATF_REQUIRE_EQ_MSG(lookup_me, magic,
1946 "got value %" PRIx8 " != expected %" PRIx8, lookup_me, magic);
1947
1948 printf("Before resuming the child process where it left off and "
1949 "without signal to be sent\n");
1950 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1951
1952 printf("Before calling %s() for the child\n", TWAIT_FNAME);
1953 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1954
1955 validate_status_exited(status, exitval);
1956
1957 printf("Before calling %s() for the child\n", TWAIT_FNAME);
1958 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1959 }
1960
1961 ATF_TC(io_read_d2);
ATF_TC_HEAD(io_read_d2,tc)1962 ATF_TC_HEAD(io_read_d2, tc)
1963 {
1964 atf_tc_set_md_var(tc, "descr",
1965 "Verify PT_IO with PIOD_READ_D and len = sizeof(uint16_t)");
1966 }
1967
ATF_TC_BODY(io_read_d2,tc)1968 ATF_TC_BODY(io_read_d2, tc)
1969 {
1970 const int exitval = 5;
1971 const int sigval = SIGSTOP;
1972 pid_t child, wpid;
1973 uint16_t lookup_me = 0;
1974 const uint16_t magic = 0x1234;
1975 struct ptrace_io_desc io = {
1976 .piod_op = PIOD_READ_D,
1977 .piod_offs = &lookup_me,
1978 .piod_addr = &lookup_me,
1979 .piod_len = sizeof(lookup_me)
1980 };
1981 #if defined(TWAIT_HAVE_STATUS)
1982 int status;
1983 #endif
1984
1985 printf("Before forking process PID=%d\n", getpid());
1986 ATF_REQUIRE((child = fork()) != -1);
1987 if (child == 0) {
1988 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
1989 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1990
1991 lookup_me = magic;
1992
1993 printf("Before raising %s from child\n", strsignal(sigval));
1994 FORKEE_ASSERT(raise(sigval) == 0);
1995
1996 printf("Before exiting of the child process\n");
1997 _exit(exitval);
1998 }
1999 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
2000
2001 printf("Before calling %s() for the child\n", TWAIT_FNAME);
2002 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2003
2004 validate_status_stopped(status, sigval);
2005
2006 printf("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
2007 child, getpid());
2008 ATF_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
2009
2010 ATF_REQUIRE_EQ_MSG(lookup_me, magic,
2011 "got value %" PRIx16 " != expected %" PRIx16, lookup_me, magic);
2012
2013 printf("Before resuming the child process where it left off and "
2014 "without signal to be sent\n");
2015 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
2016
2017 printf("Before calling %s() for the child\n", TWAIT_FNAME);
2018 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2019
2020 validate_status_exited(status, exitval);
2021
2022 printf("Before calling %s() for the child\n", TWAIT_FNAME);
2023 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
2024 }
2025
2026 ATF_TC(io_read_d3);
ATF_TC_HEAD(io_read_d3,tc)2027 ATF_TC_HEAD(io_read_d3, tc)
2028 {
2029 atf_tc_set_md_var(tc, "descr",
2030 "Verify PT_IO with PIOD_READ_D and len = sizeof(uint32_t)");
2031 }
2032
ATF_TC_BODY(io_read_d3,tc)2033 ATF_TC_BODY(io_read_d3, tc)
2034 {
2035 const int exitval = 5;
2036 const int sigval = SIGSTOP;
2037 pid_t child, wpid;
2038 uint32_t lookup_me = 0;
2039 const uint32_t magic = 0x1234abcd;
2040 struct ptrace_io_desc io = {
2041 .piod_op = PIOD_READ_D,
2042 .piod_offs = &lookup_me,
2043 .piod_addr = &lookup_me,
2044 .piod_len = sizeof(lookup_me)
2045 };
2046 #if defined(TWAIT_HAVE_STATUS)
2047 int status;
2048 #endif
2049
2050 printf("Before forking process PID=%d\n", getpid());
2051 ATF_REQUIRE((child = fork()) != -1);
2052 if (child == 0) {
2053 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
2054 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
2055
2056 lookup_me = magic;
2057
2058 printf("Before raising %s from child\n", strsignal(sigval));
2059 FORKEE_ASSERT(raise(sigval) == 0);
2060
2061 printf("Before exiting of the child process\n");
2062 _exit(exitval);
2063 }
2064 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
2065
2066 printf("Before calling %s() for the child\n", TWAIT_FNAME);
2067 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2068
2069 validate_status_stopped(status, sigval);
2070
2071 printf("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
2072 child, getpid());
2073 ATF_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
2074
2075 ATF_REQUIRE_EQ_MSG(lookup_me, magic,
2076 "got value %" PRIx32 " != expected %" PRIx32, lookup_me, magic);
2077
2078 printf("Before resuming the child process where it left off and "
2079 "without signal to be sent\n");
2080 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
2081
2082 printf("Before calling %s() for the child\n", TWAIT_FNAME);
2083 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2084
2085 validate_status_exited(status, exitval);
2086
2087 printf("Before calling %s() for the child\n", TWAIT_FNAME);
2088 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
2089 }
2090
2091 ATF_TC(io_read_d4);
ATF_TC_HEAD(io_read_d4,tc)2092 ATF_TC_HEAD(io_read_d4, tc)
2093 {
2094 atf_tc_set_md_var(tc, "descr",
2095 "Verify PT_IO with PIOD_READ_D and len = sizeof(uint64_t)");
2096 }
2097
ATF_TC_BODY(io_read_d4,tc)2098 ATF_TC_BODY(io_read_d4, tc)
2099 {
2100 const int exitval = 5;
2101 const int sigval = SIGSTOP;
2102 pid_t child, wpid;
2103 uint64_t lookup_me = 0;
2104 const uint64_t magic = 0x1234abcd9876dcfa;
2105 struct ptrace_io_desc io = {
2106 .piod_op = PIOD_READ_D,
2107 .piod_offs = &lookup_me,
2108 .piod_addr = &lookup_me,
2109 .piod_len = sizeof(lookup_me)
2110 };
2111 #if defined(TWAIT_HAVE_STATUS)
2112 int status;
2113 #endif
2114
2115 printf("Before forking process PID=%d\n", getpid());
2116 ATF_REQUIRE((child = fork()) != -1);
2117 if (child == 0) {
2118 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
2119 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
2120
2121 lookup_me = magic;
2122
2123 printf("Before raising %s from child\n", strsignal(sigval));
2124 FORKEE_ASSERT(raise(sigval) == 0);
2125
2126 printf("Before exiting of the child process\n");
2127 _exit(exitval);
2128 }
2129 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
2130
2131 printf("Before calling %s() for the child\n", TWAIT_FNAME);
2132 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2133
2134 validate_status_stopped(status, sigval);
2135
2136 printf("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
2137 child, getpid());
2138 ATF_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
2139
2140 ATF_REQUIRE_EQ_MSG(lookup_me, magic,
2141 "got value %" PRIx64 " != expected %" PRIx64, lookup_me, magic);
2142
2143 printf("Before resuming the child process where it left off and "
2144 "without signal to be sent\n");
2145 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
2146
2147 printf("Before calling %s() for the child\n", TWAIT_FNAME);
2148 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2149
2150 validate_status_exited(status, exitval);
2151
2152 printf("Before calling %s() for the child\n", TWAIT_FNAME);
2153 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
2154 }
2155
2156 ATF_TC(io_write_d1);
ATF_TC_HEAD(io_write_d1,tc)2157 ATF_TC_HEAD(io_write_d1, tc)
2158 {
2159 atf_tc_set_md_var(tc, "descr",
2160 "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint8_t)");
2161 }
2162
ATF_TC_BODY(io_write_d1,tc)2163 ATF_TC_BODY(io_write_d1, tc)
2164 {
2165 const int exitval = 5;
2166 const int sigval = SIGSTOP;
2167 pid_t child, wpid;
2168 uint8_t lookup_me = 0;
2169 const uint8_t magic = 0xab;
2170 struct ptrace_io_desc io = {
2171 .piod_op = PIOD_WRITE_D,
2172 .piod_offs = &lookup_me,
2173 .piod_addr = &lookup_me,
2174 .piod_len = sizeof(lookup_me)
2175 };
2176 #if defined(TWAIT_HAVE_STATUS)
2177 int status;
2178 #endif
2179
2180 printf("Before forking process PID=%d\n", getpid());
2181 ATF_REQUIRE((child = fork()) != -1);
2182 if (child == 0) {
2183 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
2184 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
2185
2186 printf("Before raising %s from child\n", strsignal(sigval));
2187 FORKEE_ASSERT(raise(sigval) == 0);
2188
2189 FORKEE_ASSERT_EQ(lookup_me, magic);
2190
2191 printf("Before exiting of the child process\n");
2192 _exit(exitval);
2193 }
2194 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
2195
2196 printf("Before calling %s() for the child\n", TWAIT_FNAME);
2197 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2198
2199 validate_status_stopped(status, sigval);
2200
2201 lookup_me = magic;
2202
2203 printf("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
2204 child, getpid());
2205 ATF_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
2206
2207 printf("Before resuming the child process where it left off and "
2208 "without signal to be sent\n");
2209 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
2210
2211 printf("Before calling %s() for the child\n", TWAIT_FNAME);
2212 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2213
2214 validate_status_exited(status, exitval);
2215
2216 printf("Before calling %s() for the child\n", TWAIT_FNAME);
2217 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
2218 }
2219
2220 ATF_TC(io_write_d2);
ATF_TC_HEAD(io_write_d2,tc)2221 ATF_TC_HEAD(io_write_d2, tc)
2222 {
2223 atf_tc_set_md_var(tc, "descr",
2224 "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint16_t)");
2225 }
2226
ATF_TC_BODY(io_write_d2,tc)2227 ATF_TC_BODY(io_write_d2, tc)
2228 {
2229 const int exitval = 5;
2230 const int sigval = SIGSTOP;
2231 pid_t child, wpid;
2232 uint16_t lookup_me = 0;
2233 const uint16_t magic = 0xab12;
2234 struct ptrace_io_desc io = {
2235 .piod_op = PIOD_WRITE_D,
2236 .piod_offs = &lookup_me,
2237 .piod_addr = &lookup_me,
2238 .piod_len = sizeof(lookup_me)
2239 };
2240 #if defined(TWAIT_HAVE_STATUS)
2241 int status;
2242 #endif
2243
2244 printf("Before forking process PID=%d\n", getpid());
2245 ATF_REQUIRE((child = fork()) != -1);
2246 if (child == 0) {
2247 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
2248 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
2249
2250 printf("Before raising %s from child\n", strsignal(sigval));
2251 FORKEE_ASSERT(raise(sigval) == 0);
2252
2253 FORKEE_ASSERT_EQ(lookup_me, magic);
2254
2255 printf("Before exiting of the child process\n");
2256 _exit(exitval);
2257 }
2258 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
2259
2260 printf("Before calling %s() for the child\n", TWAIT_FNAME);
2261 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2262
2263 validate_status_stopped(status, sigval);
2264
2265 lookup_me = magic;
2266
2267 printf("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
2268 child, getpid());
2269 ATF_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
2270
2271 printf("Before resuming the child process where it left off and "
2272 "without signal to be sent\n");
2273 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
2274
2275 printf("Before calling %s() for the child\n", TWAIT_FNAME);
2276 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2277
2278 validate_status_exited(status, exitval);
2279
2280 printf("Before calling %s() for the child\n", TWAIT_FNAME);
2281 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
2282 }
2283
2284 ATF_TC(io_write_d3);
ATF_TC_HEAD(io_write_d3,tc)2285 ATF_TC_HEAD(io_write_d3, tc)
2286 {
2287 atf_tc_set_md_var(tc, "descr",
2288 "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint32_t)");
2289 }
2290
ATF_TC_BODY(io_write_d3,tc)2291 ATF_TC_BODY(io_write_d3, tc)
2292 {
2293 const int exitval = 5;
2294 const int sigval = SIGSTOP;
2295 pid_t child, wpid;
2296 uint32_t lookup_me = 0;
2297 const uint32_t magic = 0xab127643;
2298 struct ptrace_io_desc io = {
2299 .piod_op = PIOD_WRITE_D,
2300 .piod_offs = &lookup_me,
2301 .piod_addr = &lookup_me,
2302 .piod_len = sizeof(lookup_me)
2303 };
2304 #if defined(TWAIT_HAVE_STATUS)
2305 int status;
2306 #endif
2307
2308 printf("Before forking process PID=%d\n", getpid());
2309 ATF_REQUIRE((child = fork()) != -1);
2310 if (child == 0) {
2311 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
2312 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
2313
2314 printf("Before raising %s from child\n", strsignal(sigval));
2315 FORKEE_ASSERT(raise(sigval) == 0);
2316
2317 FORKEE_ASSERT_EQ(lookup_me, magic);
2318
2319 printf("Before exiting of the child process\n");
2320 _exit(exitval);
2321 }
2322 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
2323
2324 printf("Before calling %s() for the child\n", TWAIT_FNAME);
2325 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2326
2327 validate_status_stopped(status, sigval);
2328
2329 lookup_me = magic;
2330
2331 printf("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
2332 child, getpid());
2333 ATF_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
2334
2335 printf("Before resuming the child process where it left off and "
2336 "without signal to be sent\n");
2337 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
2338
2339 printf("Before calling %s() for the child\n", TWAIT_FNAME);
2340 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2341
2342 validate_status_exited(status, exitval);
2343
2344 printf("Before calling %s() for the child\n", TWAIT_FNAME);
2345 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
2346 }
2347
2348 ATF_TC(io_write_d4);
ATF_TC_HEAD(io_write_d4,tc)2349 ATF_TC_HEAD(io_write_d4, tc)
2350 {
2351 atf_tc_set_md_var(tc, "descr",
2352 "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint64_t)");
2353 }
2354
ATF_TC_BODY(io_write_d4,tc)2355 ATF_TC_BODY(io_write_d4, tc)
2356 {
2357 const int exitval = 5;
2358 const int sigval = SIGSTOP;
2359 pid_t child, wpid;
2360 uint64_t lookup_me = 0;
2361 const uint64_t magic = 0xab12764376490123;
2362 struct ptrace_io_desc io = {
2363 .piod_op = PIOD_WRITE_D,
2364 .piod_offs = &lookup_me,
2365 .piod_addr = &lookup_me,
2366 .piod_len = sizeof(lookup_me)
2367 };
2368 #if defined(TWAIT_HAVE_STATUS)
2369 int status;
2370 #endif
2371
2372 printf("Before forking process PID=%d\n", getpid());
2373 ATF_REQUIRE((child = fork()) != -1);
2374 if (child == 0) {
2375 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
2376 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
2377
2378 printf("Before raising %s from child\n", strsignal(sigval));
2379 FORKEE_ASSERT(raise(sigval) == 0);
2380
2381 FORKEE_ASSERT_EQ(lookup_me, magic);
2382
2383 printf("Before exiting of the child process\n");
2384 _exit(exitval);
2385 }
2386 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
2387
2388 printf("Before calling %s() for the child\n", TWAIT_FNAME);
2389 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2390
2391 validate_status_stopped(status, sigval);
2392
2393 lookup_me = magic;
2394
2395 printf("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
2396 child, getpid());
2397 ATF_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
2398
2399 printf("Before resuming the child process where it left off and "
2400 "without signal to be sent\n");
2401 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
2402
2403 printf("Before calling %s() for the child\n", TWAIT_FNAME);
2404 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2405
2406 validate_status_exited(status, exitval);
2407
2408 printf("Before calling %s() for the child\n", TWAIT_FNAME);
2409 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
2410 }
2411
2412 ATF_TC(io_read_auxv1);
ATF_TC_HEAD(io_read_auxv1,tc)2413 ATF_TC_HEAD(io_read_auxv1, tc)
2414 {
2415 atf_tc_set_md_var(tc, "descr",
2416 "Verify PT_READ_AUXV called for tracee");
2417 }
2418
ATF_TC_BODY(io_read_auxv1,tc)2419 ATF_TC_BODY(io_read_auxv1, tc)
2420 {
2421 const int exitval = 5;
2422 const int sigval = SIGSTOP;
2423 pid_t child, wpid;
2424 #if defined(TWAIT_HAVE_STATUS)
2425 int status;
2426 #endif
2427 AuxInfo ai[100], *aip;
2428 struct ptrace_io_desc io = {
2429 .piod_op = PIOD_READ_AUXV,
2430 .piod_offs = 0,
2431 .piod_addr = ai,
2432 .piod_len = sizeof(ai)
2433 };
2434
2435 printf("Before forking process PID=%d\n", getpid());
2436 ATF_REQUIRE((child = fork()) != -1);
2437 if (child == 0) {
2438 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
2439 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
2440
2441 printf("Before raising %s from child\n", strsignal(sigval));
2442 FORKEE_ASSERT(raise(sigval) == 0);
2443
2444 printf("Before exiting of the child process\n");
2445 _exit(exitval);
2446 }
2447 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
2448
2449 printf("Before calling %s() for the child\n", TWAIT_FNAME);
2450 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2451
2452 validate_status_stopped(status, sigval);
2453
2454 printf("Read new AUXV from tracee (PID=%d) by tracer (PID=%d)\n",
2455 child, getpid());
2456 ATF_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
2457
2458 printf("Asserting that AUXV length (%zu) is > 0\n", io.piod_len);
2459 ATF_REQUIRE(io.piod_len > 0);
2460
2461 for (aip = ai; aip->a_type != AT_NULL; aip++)
2462 printf("a_type=%#llx a_v=%#llx\n",
2463 (long long int)aip->a_type, (long long int)aip->a_v);
2464
2465 printf("Before resuming the child process where it left off and "
2466 "without signal to be sent\n");
2467 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
2468
2469 printf("Before calling %s() for the child\n", TWAIT_FNAME);
2470 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2471
2472 validate_status_exited(status, exitval);
2473
2474 printf("Before calling %s() for the child\n", TWAIT_FNAME);
2475 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
2476 }
2477
2478 ATF_TC(read_d1);
ATF_TC_HEAD(read_d1,tc)2479 ATF_TC_HEAD(read_d1, tc)
2480 {
2481 atf_tc_set_md_var(tc, "descr",
2482 "Verify PT_READ_D called once");
2483 }
2484
ATF_TC_BODY(read_d1,tc)2485 ATF_TC_BODY(read_d1, tc)
2486 {
2487 const int exitval = 5;
2488 const int sigval = SIGSTOP;
2489 pid_t child, wpid;
2490 int lookup_me = 0;
2491 const int magic = (int)random();
2492 #if defined(TWAIT_HAVE_STATUS)
2493 int status;
2494 #endif
2495
2496 printf("Before forking process PID=%d\n", getpid());
2497 ATF_REQUIRE((child = fork()) != -1);
2498 if (child == 0) {
2499 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
2500 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
2501
2502 lookup_me = magic;
2503
2504 printf("Before raising %s from child\n", strsignal(sigval));
2505 FORKEE_ASSERT(raise(sigval) == 0);
2506
2507 printf("Before exiting of the child process\n");
2508 _exit(exitval);
2509 }
2510 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
2511
2512 printf("Before calling %s() for the child\n", TWAIT_FNAME);
2513 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2514
2515 validate_status_stopped(status, sigval);
2516
2517 printf("Read new lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
2518 child, getpid());
2519 errno = 0;
2520 lookup_me = ptrace(PT_READ_D, child, &lookup_me, 0);
2521 ATF_REQUIRE_EQ(errno, 0);
2522
2523 ATF_REQUIRE_EQ_MSG(lookup_me, magic,
2524 "got value %#x != expected %#x", lookup_me, magic);
2525
2526 printf("Before resuming the child process where it left off and "
2527 "without signal to be sent\n");
2528 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
2529
2530 printf("Before calling %s() for the child\n", TWAIT_FNAME);
2531 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2532
2533 validate_status_exited(status, exitval);
2534
2535 printf("Before calling %s() for the child\n", TWAIT_FNAME);
2536 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
2537 }
2538
2539 ATF_TC(read_d2);
ATF_TC_HEAD(read_d2,tc)2540 ATF_TC_HEAD(read_d2, tc)
2541 {
2542 atf_tc_set_md_var(tc, "descr",
2543 "Verify PT_READ_D called twice");
2544 }
2545
ATF_TC_BODY(read_d2,tc)2546 ATF_TC_BODY(read_d2, tc)
2547 {
2548 const int exitval = 5;
2549 const int sigval = SIGSTOP;
2550 pid_t child, wpid;
2551 int lookup_me1 = 0;
2552 int lookup_me2 = 0;
2553 const int magic1 = (int)random();
2554 const int magic2 = (int)random();
2555 #if defined(TWAIT_HAVE_STATUS)
2556 int status;
2557 #endif
2558
2559 printf("Before forking process PID=%d\n", getpid());
2560 ATF_REQUIRE((child = fork()) != -1);
2561 if (child == 0) {
2562 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
2563 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
2564
2565 lookup_me1 = magic1;
2566 lookup_me2 = magic2;
2567
2568 printf("Before raising %s from child\n", strsignal(sigval));
2569 FORKEE_ASSERT(raise(sigval) == 0);
2570
2571 printf("Before exiting of the child process\n");
2572 _exit(exitval);
2573 }
2574 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
2575
2576 printf("Before calling %s() for the child\n", TWAIT_FNAME);
2577 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2578
2579 validate_status_stopped(status, sigval);
2580
2581 printf("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
2582 child, getpid());
2583 errno = 0;
2584 lookup_me1 = ptrace(PT_READ_D, child, &lookup_me1, 0);
2585 ATF_REQUIRE_EQ(errno, 0);
2586
2587 ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
2588 "got value %#x != expected %#x", lookup_me1, magic1);
2589
2590 printf("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
2591 child, getpid());
2592 errno = 0;
2593 lookup_me2 = ptrace(PT_READ_D, child, &lookup_me2, 0);
2594 ATF_REQUIRE_EQ(errno, 0);
2595
2596 ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
2597 "got value %#x != expected %#x", lookup_me2, magic2);
2598
2599 printf("Before resuming the child process where it left off and "
2600 "without signal to be sent\n");
2601 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
2602
2603 printf("Before calling %s() for the child\n", TWAIT_FNAME);
2604 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2605
2606 validate_status_exited(status, exitval);
2607
2608 printf("Before calling %s() for the child\n", TWAIT_FNAME);
2609 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
2610 }
2611
2612 ATF_TC(read_d3);
ATF_TC_HEAD(read_d3,tc)2613 ATF_TC_HEAD(read_d3, tc)
2614 {
2615 atf_tc_set_md_var(tc, "descr",
2616 "Verify PT_READ_D called three times");
2617 }
2618
ATF_TC_BODY(read_d3,tc)2619 ATF_TC_BODY(read_d3, tc)
2620 {
2621 const int exitval = 5;
2622 const int sigval = SIGSTOP;
2623 pid_t child, wpid;
2624 int lookup_me1 = 0;
2625 int lookup_me2 = 0;
2626 int lookup_me3 = 0;
2627 const int magic1 = (int)random();
2628 const int magic2 = (int)random();
2629 const int magic3 = (int)random();
2630 #if defined(TWAIT_HAVE_STATUS)
2631 int status;
2632 #endif
2633
2634 printf("Before forking process PID=%d\n", getpid());
2635 ATF_REQUIRE((child = fork()) != -1);
2636 if (child == 0) {
2637 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
2638 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
2639
2640 lookup_me1 = magic1;
2641 lookup_me2 = magic2;
2642 lookup_me3 = magic3;
2643
2644 printf("Before raising %s from child\n", strsignal(sigval));
2645 FORKEE_ASSERT(raise(sigval) == 0);
2646
2647 printf("Before exiting of the child process\n");
2648 _exit(exitval);
2649 }
2650 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
2651
2652 printf("Before calling %s() for the child\n", TWAIT_FNAME);
2653 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2654
2655 validate_status_stopped(status, sigval);
2656
2657 printf("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
2658 child, getpid());
2659 errno = 0;
2660 lookup_me1 = ptrace(PT_READ_D, child, &lookup_me1, 0);
2661 ATF_REQUIRE_EQ(errno, 0);
2662
2663 ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
2664 "got value %#x != expected %#x", lookup_me1, magic1);
2665
2666 printf("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
2667 child, getpid());
2668 errno = 0;
2669 lookup_me2 = ptrace(PT_READ_D, child, &lookup_me2, 0);
2670 ATF_REQUIRE_EQ(errno, 0);
2671
2672 ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
2673 "got value %#x != expected %#x", lookup_me2, magic2);
2674
2675 printf("Read new lookup_me3 from tracee (PID=%d) by tracer (PID=%d)\n",
2676 child, getpid());
2677 errno = 0;
2678 lookup_me3 = ptrace(PT_READ_D, child, &lookup_me3, 0);
2679 ATF_REQUIRE_EQ(errno, 0);
2680
2681 ATF_REQUIRE_EQ_MSG(lookup_me3, magic3,
2682 "got value %#x != expected %#x", lookup_me3, magic3);
2683
2684 printf("Before resuming the child process where it left off and "
2685 "without signal to be sent\n");
2686 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
2687
2688 printf("Before calling %s() for the child\n", TWAIT_FNAME);
2689 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2690
2691 validate_status_exited(status, exitval);
2692
2693 printf("Before calling %s() for the child\n", TWAIT_FNAME);
2694 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
2695 }
2696
2697 ATF_TC(read_d4);
ATF_TC_HEAD(read_d4,tc)2698 ATF_TC_HEAD(read_d4, tc)
2699 {
2700 atf_tc_set_md_var(tc, "descr",
2701 "Verify PT_READ_D called four times");
2702 }
2703
ATF_TC_BODY(read_d4,tc)2704 ATF_TC_BODY(read_d4, tc)
2705 {
2706 const int exitval = 5;
2707 const int sigval = SIGSTOP;
2708 pid_t child, wpid;
2709 int lookup_me1 = 0;
2710 int lookup_me2 = 0;
2711 int lookup_me3 = 0;
2712 int lookup_me4 = 0;
2713 const int magic1 = (int)random();
2714 const int magic2 = (int)random();
2715 const int magic3 = (int)random();
2716 const int magic4 = (int)random();
2717 #if defined(TWAIT_HAVE_STATUS)
2718 int status;
2719 #endif
2720
2721 printf("Before forking process PID=%d\n", getpid());
2722 ATF_REQUIRE((child = fork()) != -1);
2723 if (child == 0) {
2724 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
2725 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
2726
2727 lookup_me1 = magic1;
2728 lookup_me2 = magic2;
2729 lookup_me3 = magic3;
2730 lookup_me4 = magic4;
2731
2732 printf("Before raising %s from child\n", strsignal(sigval));
2733 FORKEE_ASSERT(raise(sigval) == 0);
2734
2735 printf("Before exiting of the child process\n");
2736 _exit(exitval);
2737 }
2738 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
2739
2740 printf("Before calling %s() for the child\n", TWAIT_FNAME);
2741 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2742
2743 validate_status_stopped(status, sigval);
2744
2745 printf("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
2746 child, getpid());
2747 errno = 0;
2748 lookup_me1 = ptrace(PT_READ_D, child, &lookup_me1, 0);
2749 ATF_REQUIRE_EQ(errno, 0);
2750
2751 ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
2752 "got value %#x != expected %#x", lookup_me1, magic1);
2753
2754 printf("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
2755 child, getpid());
2756 errno = 0;
2757 lookup_me2 = ptrace(PT_READ_D, child, &lookup_me2, 0);
2758 ATF_REQUIRE_EQ(errno, 0);
2759
2760 ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
2761 "got value %#x != expected %#x", lookup_me2, magic2);
2762
2763 printf("Read new lookup_me3 from tracee (PID=%d) by tracer (PID=%d)\n",
2764 child, getpid());
2765 errno = 0;
2766 lookup_me3 = ptrace(PT_READ_D, child, &lookup_me3, 0);
2767 ATF_REQUIRE_EQ(errno, 0);
2768
2769 ATF_REQUIRE_EQ_MSG(lookup_me3, magic3,
2770 "got value %#x != expected %#x", lookup_me3, magic3);
2771
2772 printf("Read new lookup_me4 from tracee (PID=%d) by tracer (PID=%d)\n",
2773 child, getpid());
2774 errno = 0;
2775 lookup_me4 = ptrace(PT_READ_D, child, &lookup_me4, 0);
2776 ATF_REQUIRE_EQ(errno, 0);
2777
2778 ATF_REQUIRE_EQ_MSG(lookup_me4, magic4,
2779 "got value %#x != expected %#x", lookup_me4, magic4);
2780
2781 printf("Before resuming the child process where it left off and "
2782 "without signal to be sent\n");
2783 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
2784
2785 printf("Before calling %s() for the child\n", TWAIT_FNAME);
2786 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2787
2788 validate_status_exited(status, exitval);
2789
2790 printf("Before calling %s() for the child\n", TWAIT_FNAME);
2791 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
2792 }
2793
2794 ATF_TC(write_d1);
ATF_TC_HEAD(write_d1,tc)2795 ATF_TC_HEAD(write_d1, tc)
2796 {
2797 atf_tc_set_md_var(tc, "descr",
2798 "Verify PT_WRITE_D called once");
2799 }
2800
ATF_TC_BODY(write_d1,tc)2801 ATF_TC_BODY(write_d1, tc)
2802 {
2803 const int exitval = 5;
2804 const int sigval = SIGSTOP;
2805 pid_t child, wpid;
2806 int lookup_me = 0;
2807 const int magic = (int)random();
2808 #if defined(TWAIT_HAVE_STATUS)
2809 int status;
2810 #endif
2811
2812 printf("Before forking process PID=%d\n", getpid());
2813 ATF_REQUIRE((child = fork()) != -1);
2814 if (child == 0) {
2815 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
2816 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
2817
2818 printf("Before raising %s from child\n", strsignal(sigval));
2819 FORKEE_ASSERT(raise(sigval) == 0);
2820
2821 FORKEE_ASSERT_EQ(lookup_me, magic);
2822
2823 printf("Before exiting of the child process\n");
2824 _exit(exitval);
2825 }
2826 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
2827
2828 printf("Before calling %s() for the child\n", TWAIT_FNAME);
2829 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2830
2831 validate_status_stopped(status, sigval);
2832
2833 printf("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
2834 child, getpid());
2835 ATF_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me, magic) != -1);
2836
2837 printf("Before resuming the child process where it left off and "
2838 "without signal to be sent\n");
2839 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
2840
2841 printf("Before calling %s() for the child\n", TWAIT_FNAME);
2842 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2843
2844 validate_status_exited(status, exitval);
2845
2846 printf("Before calling %s() for the child\n", TWAIT_FNAME);
2847 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
2848 }
2849
2850 ATF_TC(write_d2);
ATF_TC_HEAD(write_d2,tc)2851 ATF_TC_HEAD(write_d2, tc)
2852 {
2853 atf_tc_set_md_var(tc, "descr",
2854 "Verify PT_WRITE_D called twice");
2855 }
2856
ATF_TC_BODY(write_d2,tc)2857 ATF_TC_BODY(write_d2, tc)
2858 {
2859 const int exitval = 5;
2860 const int sigval = SIGSTOP;
2861 pid_t child, wpid;
2862 int lookup_me1 = 0;
2863 int lookup_me2 = 0;
2864 const int magic1 = (int)random();
2865 const int magic2 = (int)random();
2866 #if defined(TWAIT_HAVE_STATUS)
2867 int status;
2868 #endif
2869
2870 printf("Before forking process PID=%d\n", getpid());
2871 ATF_REQUIRE((child = fork()) != -1);
2872 if (child == 0) {
2873 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
2874 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
2875
2876 printf("Before raising %s from child\n", strsignal(sigval));
2877 FORKEE_ASSERT(raise(sigval) == 0);
2878
2879 FORKEE_ASSERT_EQ(lookup_me1, magic1);
2880 FORKEE_ASSERT_EQ(lookup_me2, magic2);
2881
2882 printf("Before exiting of the child process\n");
2883 _exit(exitval);
2884 }
2885 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
2886
2887 printf("Before calling %s() for the child\n", TWAIT_FNAME);
2888 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2889
2890 validate_status_stopped(status, sigval);
2891
2892 printf("Write new lookup_me1 to tracee (PID=%d) from tracer (PID=%d)\n",
2893 child, getpid());
2894 ATF_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me1, magic1) != -1);
2895
2896 printf("Write new lookup_me2 to tracee (PID=%d) from tracer (PID=%d)\n",
2897 child, getpid());
2898 ATF_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me2, magic2) != -1);
2899
2900 printf("Before resuming the child process where it left off and "
2901 "without signal to be sent\n");
2902 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
2903
2904 printf("Before calling %s() for the child\n", TWAIT_FNAME);
2905 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2906
2907 validate_status_exited(status, exitval);
2908
2909 printf("Before calling %s() for the child\n", TWAIT_FNAME);
2910 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
2911 }
2912
2913 ATF_TC(write_d3);
ATF_TC_HEAD(write_d3,tc)2914 ATF_TC_HEAD(write_d3, tc)
2915 {
2916 atf_tc_set_md_var(tc, "descr",
2917 "Verify PT_WRITE_D called three times");
2918 }
2919
ATF_TC_BODY(write_d3,tc)2920 ATF_TC_BODY(write_d3, tc)
2921 {
2922 const int exitval = 5;
2923 const int sigval = SIGSTOP;
2924 pid_t child, wpid;
2925 int lookup_me1 = 0;
2926 int lookup_me2 = 0;
2927 int lookup_me3 = 0;
2928 const int magic1 = (int)random();
2929 const int magic2 = (int)random();
2930 const int magic3 = (int)random();
2931 #if defined(TWAIT_HAVE_STATUS)
2932 int status;
2933 #endif
2934
2935 printf("Before forking process PID=%d\n", getpid());
2936 ATF_REQUIRE((child = fork()) != -1);
2937 if (child == 0) {
2938 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
2939 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
2940
2941 printf("Before raising %s from child\n", strsignal(sigval));
2942 FORKEE_ASSERT(raise(sigval) == 0);
2943
2944 FORKEE_ASSERT_EQ(lookup_me1, magic1);
2945 FORKEE_ASSERT_EQ(lookup_me2, magic2);
2946 FORKEE_ASSERT_EQ(lookup_me3, magic3);
2947
2948 printf("Before exiting of the child process\n");
2949 _exit(exitval);
2950 }
2951 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
2952
2953 printf("Before calling %s() for the child\n", TWAIT_FNAME);
2954 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2955
2956 validate_status_stopped(status, sigval);
2957
2958 printf("Write new lookup_me1 to tracee (PID=%d) from tracer (PID=%d)\n",
2959 child, getpid());
2960 ATF_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me1, magic1) != -1);
2961
2962 printf("Write new lookup_me2 to tracee (PID=%d) from tracer (PID=%d)\n",
2963 child, getpid());
2964 ATF_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me2, magic2) != -1);
2965
2966 printf("Write new lookup_me3 to tracee (PID=%d) from tracer (PID=%d)\n",
2967 child, getpid());
2968 ATF_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me3, magic3) != -1);
2969
2970 printf("Before resuming the child process where it left off and "
2971 "without signal to be sent\n");
2972 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
2973
2974 printf("Before calling %s() for the child\n", TWAIT_FNAME);
2975 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2976
2977 validate_status_exited(status, exitval);
2978
2979 printf("Before calling %s() for the child\n", TWAIT_FNAME);
2980 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
2981 }
2982
2983 ATF_TC(write_d4);
ATF_TC_HEAD(write_d4,tc)2984 ATF_TC_HEAD(write_d4, tc)
2985 {
2986 atf_tc_set_md_var(tc, "descr",
2987 "Verify PT_WRITE_D called four times");
2988 }
2989
ATF_TC_BODY(write_d4,tc)2990 ATF_TC_BODY(write_d4, tc)
2991 {
2992 const int exitval = 5;
2993 const int sigval = SIGSTOP;
2994 pid_t child, wpid;
2995 int lookup_me1 = 0;
2996 int lookup_me2 = 0;
2997 int lookup_me3 = 0;
2998 int lookup_me4 = 0;
2999 const int magic1 = (int)random();
3000 const int magic2 = (int)random();
3001 const int magic3 = (int)random();
3002 const int magic4 = (int)random();
3003 #if defined(TWAIT_HAVE_STATUS)
3004 int status;
3005 #endif
3006
3007 printf("Before forking process PID=%d\n", getpid());
3008 ATF_REQUIRE((child = fork()) != -1);
3009 if (child == 0) {
3010 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
3011 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
3012
3013 printf("Before raising %s from child\n", strsignal(sigval));
3014 FORKEE_ASSERT(raise(sigval) == 0);
3015
3016 FORKEE_ASSERT_EQ(lookup_me1, magic1);
3017 FORKEE_ASSERT_EQ(lookup_me2, magic2);
3018 FORKEE_ASSERT_EQ(lookup_me3, magic3);
3019 FORKEE_ASSERT_EQ(lookup_me4, magic4);
3020
3021 printf("Before exiting of the child process\n");
3022 _exit(exitval);
3023 }
3024 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
3025
3026 printf("Before calling %s() for the child\n", TWAIT_FNAME);
3027 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3028
3029 validate_status_stopped(status, sigval);
3030
3031 printf("Write new lookup_me1 to tracee (PID=%d) from tracer (PID=%d)\n",
3032 child, getpid());
3033 ATF_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me1, magic1) != -1);
3034
3035 printf("Write new lookup_me2 to tracee (PID=%d) from tracer (PID=%d)\n",
3036 child, getpid());
3037 ATF_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me2, magic2) != -1);
3038
3039 printf("Write new lookup_me3 to tracee (PID=%d) from tracer (PID=%d)\n",
3040 child, getpid());
3041 ATF_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me3, magic3) != -1);
3042
3043 printf("Write new lookup_me4 to tracee (PID=%d) from tracer (PID=%d)\n",
3044 child, getpid());
3045 ATF_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me4, magic4) != -1);
3046
3047 printf("Before resuming the child process where it left off and "
3048 "without signal to be sent\n");
3049 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
3050
3051 printf("Before calling %s() for the child\n", TWAIT_FNAME);
3052 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3053
3054 validate_status_exited(status, exitval);
3055
3056 printf("Before calling %s() for the child\n", TWAIT_FNAME);
3057 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
3058 }
3059
3060 ATF_TC(io_read_d_write_d_handshake1);
ATF_TC_HEAD(io_read_d_write_d_handshake1,tc)3061 ATF_TC_HEAD(io_read_d_write_d_handshake1, tc)
3062 {
3063 atf_tc_set_md_var(tc, "descr",
3064 "Verify PT_IO with PIOD_READ_D and PIOD_WRITE_D handshake");
3065 }
3066
ATF_TC_BODY(io_read_d_write_d_handshake1,tc)3067 ATF_TC_BODY(io_read_d_write_d_handshake1, tc)
3068 {
3069 const int exitval = 5;
3070 const int sigval = SIGSTOP;
3071 pid_t child, wpid;
3072 uint8_t lookup_me_fromtracee = 0;
3073 const uint8_t magic_fromtracee = (uint8_t)random();
3074 uint8_t lookup_me_totracee = 0;
3075 const uint8_t magic_totracee = (uint8_t)random();
3076 struct ptrace_io_desc io_fromtracee = {
3077 .piod_op = PIOD_READ_D,
3078 .piod_offs = &lookup_me_fromtracee,
3079 .piod_addr = &lookup_me_fromtracee,
3080 .piod_len = sizeof(lookup_me_fromtracee)
3081 };
3082 struct ptrace_io_desc io_totracee = {
3083 .piod_op = PIOD_WRITE_D,
3084 .piod_offs = &lookup_me_totracee,
3085 .piod_addr = &lookup_me_totracee,
3086 .piod_len = sizeof(lookup_me_totracee)
3087 };
3088 #if defined(TWAIT_HAVE_STATUS)
3089 int status;
3090 #endif
3091
3092 printf("Before forking process PID=%d\n", getpid());
3093 ATF_REQUIRE((child = fork()) != -1);
3094 if (child == 0) {
3095 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
3096 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
3097
3098 lookup_me_fromtracee = magic_fromtracee;
3099
3100 printf("Before raising %s from child\n", strsignal(sigval));
3101 FORKEE_ASSERT(raise(sigval) == 0);
3102
3103 FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee);
3104
3105 printf("Before exiting of the child process\n");
3106 _exit(exitval);
3107 }
3108 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
3109
3110 printf("Before calling %s() for the child\n", TWAIT_FNAME);
3111 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3112
3113 validate_status_stopped(status, sigval);
3114
3115 printf("Read lookup_me_fromtracee PID=%d by tracer (PID=%d)\n",
3116 child, getpid());
3117 ATF_REQUIRE(ptrace(PT_IO, child, &io_fromtracee, 0) != -1);
3118
3119 ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee,
3120 "got value %" PRIx8 " != expected %" PRIx8, lookup_me_fromtracee,
3121 magic_fromtracee);
3122
3123 lookup_me_totracee = magic_totracee;
3124
3125 printf("Write lookup_me_totracee to PID=%d by tracer (PID=%d)\n",
3126 child, getpid());
3127 ATF_REQUIRE(ptrace(PT_IO, child, &io_totracee, 0) != -1);
3128
3129 ATF_REQUIRE_EQ_MSG(lookup_me_totracee, magic_totracee,
3130 "got value %" PRIx8 " != expected %" PRIx8, lookup_me_totracee,
3131 magic_totracee);
3132
3133 printf("Before resuming the child process where it left off and "
3134 "without signal to be sent\n");
3135 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
3136
3137 printf("Before calling %s() for the child\n", TWAIT_FNAME);
3138 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3139
3140 validate_status_exited(status, exitval);
3141
3142 printf("Before calling %s() for the child\n", TWAIT_FNAME);
3143 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
3144 }
3145
3146 ATF_TC(io_read_d_write_d_handshake2);
ATF_TC_HEAD(io_read_d_write_d_handshake2,tc)3147 ATF_TC_HEAD(io_read_d_write_d_handshake2, tc)
3148 {
3149 atf_tc_set_md_var(tc, "descr",
3150 "Verify PT_IO with PIOD_WRITE_D and PIOD_READ_D handshake");
3151 }
3152
ATF_TC_BODY(io_read_d_write_d_handshake2,tc)3153 ATF_TC_BODY(io_read_d_write_d_handshake2, tc)
3154 {
3155 const int exitval = 5;
3156 const int sigval = SIGSTOP;
3157 pid_t child, wpid;
3158 uint8_t lookup_me_fromtracee = 0;
3159 const uint8_t magic_fromtracee = (uint8_t)random();
3160 uint8_t lookup_me_totracee = 0;
3161 const uint8_t magic_totracee = (uint8_t)random();
3162 struct ptrace_io_desc io_fromtracee = {
3163 .piod_op = PIOD_READ_D,
3164 .piod_offs = &lookup_me_fromtracee,
3165 .piod_addr = &lookup_me_fromtracee,
3166 .piod_len = sizeof(lookup_me_fromtracee)
3167 };
3168 struct ptrace_io_desc io_totracee = {
3169 .piod_op = PIOD_WRITE_D,
3170 .piod_offs = &lookup_me_totracee,
3171 .piod_addr = &lookup_me_totracee,
3172 .piod_len = sizeof(lookup_me_totracee)
3173 };
3174 #if defined(TWAIT_HAVE_STATUS)
3175 int status;
3176 #endif
3177
3178 printf("Before forking process PID=%d\n", getpid());
3179 ATF_REQUIRE((child = fork()) != -1);
3180 if (child == 0) {
3181 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
3182 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
3183
3184 lookup_me_fromtracee = magic_fromtracee;
3185
3186 printf("Before raising %s from child\n", strsignal(sigval));
3187 FORKEE_ASSERT(raise(sigval) == 0);
3188
3189 FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee);
3190
3191 printf("Before exiting of the child process\n");
3192 _exit(exitval);
3193 }
3194 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
3195
3196 printf("Before calling %s() for the child\n", TWAIT_FNAME);
3197 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3198
3199 validate_status_stopped(status, sigval);
3200
3201 lookup_me_totracee = magic_totracee;
3202
3203 printf("Write lookup_me_totracee to PID=%d by tracer (PID=%d)\n",
3204 child, getpid());
3205 ATF_REQUIRE(ptrace(PT_IO, child, &io_totracee, 0) != -1);
3206
3207 ATF_REQUIRE_EQ_MSG(lookup_me_totracee, magic_totracee,
3208 "got value %" PRIx8 " != expected %" PRIx8, lookup_me_totracee,
3209 magic_totracee);
3210
3211 printf("Read lookup_me_fromtracee PID=%d by tracer (PID=%d)\n",
3212 child, getpid());
3213 ATF_REQUIRE(ptrace(PT_IO, child, &io_fromtracee, 0) != -1);
3214
3215 ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee,
3216 "got value %" PRIx8 " != expected %" PRIx8, lookup_me_fromtracee,
3217 magic_fromtracee);
3218
3219 printf("Before resuming the child process where it left off and "
3220 "without signal to be sent\n");
3221 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
3222
3223 printf("Before calling %s() for the child\n", TWAIT_FNAME);
3224 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3225
3226 validate_status_exited(status, exitval);
3227
3228 printf("Before calling %s() for the child\n", TWAIT_FNAME);
3229 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
3230 }
3231
3232 ATF_TC(read_d_write_d_handshake1);
ATF_TC_HEAD(read_d_write_d_handshake1,tc)3233 ATF_TC_HEAD(read_d_write_d_handshake1, tc)
3234 {
3235 atf_tc_set_md_var(tc, "descr",
3236 "Verify PT_READ_D with PT_WRITE_D handshake");
3237 }
3238
ATF_TC_BODY(read_d_write_d_handshake1,tc)3239 ATF_TC_BODY(read_d_write_d_handshake1, tc)
3240 {
3241 const int exitval = 5;
3242 const int sigval = SIGSTOP;
3243 pid_t child, wpid;
3244 int lookup_me_fromtracee = 0;
3245 const int magic_fromtracee = (int)random();
3246 int lookup_me_totracee = 0;
3247 const int magic_totracee = (int)random();
3248 #if defined(TWAIT_HAVE_STATUS)
3249 int status;
3250 #endif
3251
3252 printf("Before forking process PID=%d\n", getpid());
3253 ATF_REQUIRE((child = fork()) != -1);
3254 if (child == 0) {
3255 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
3256 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
3257
3258 lookup_me_fromtracee = magic_fromtracee;
3259
3260 printf("Before raising %s from child\n", strsignal(sigval));
3261 FORKEE_ASSERT(raise(sigval) == 0);
3262
3263 FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee);
3264
3265 printf("Before exiting of the child process\n");
3266 _exit(exitval);
3267 }
3268 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
3269
3270 printf("Before calling %s() for the child\n", TWAIT_FNAME);
3271 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3272
3273 validate_status_stopped(status, sigval);
3274
3275 printf("Read new lookup_me_fromtracee PID=%d by tracer (PID=%d)\n",
3276 child, getpid());
3277 errno = 0;
3278 lookup_me_fromtracee =
3279 ptrace(PT_READ_D, child, &lookup_me_fromtracee, 0);
3280 ATF_REQUIRE_EQ(errno, 0);
3281
3282 ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee,
3283 "got value %#x != expected %#x", lookup_me_fromtracee,
3284 magic_fromtracee);
3285
3286 printf("Write new lookup_me_totracee to PID=%d from tracer (PID=%d)\n",
3287 child, getpid());
3288 ATF_REQUIRE
3289 (ptrace(PT_WRITE_D, child, &lookup_me_totracee, magic_totracee)
3290 != -1);
3291
3292 printf("Before resuming the child process where it left off and "
3293 "without signal to be sent\n");
3294 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
3295
3296 printf("Before calling %s() for the child\n", TWAIT_FNAME);
3297 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3298
3299 validate_status_exited(status, exitval);
3300
3301 printf("Before calling %s() for the child\n", TWAIT_FNAME);
3302 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
3303 }
3304
3305 ATF_TC(read_d_write_d_handshake2);
ATF_TC_HEAD(read_d_write_d_handshake2,tc)3306 ATF_TC_HEAD(read_d_write_d_handshake2, tc)
3307 {
3308 atf_tc_set_md_var(tc, "descr",
3309 "Verify PT_WRITE_D with PT_READ_D handshake");
3310 }
3311
ATF_TC_BODY(read_d_write_d_handshake2,tc)3312 ATF_TC_BODY(read_d_write_d_handshake2, tc)
3313 {
3314 const int exitval = 5;
3315 const int sigval = SIGSTOP;
3316 pid_t child, wpid;
3317 int lookup_me_fromtracee = 0;
3318 const int magic_fromtracee = (int)random();
3319 int lookup_me_totracee = 0;
3320 const int magic_totracee = (int)random();
3321 #if defined(TWAIT_HAVE_STATUS)
3322 int status;
3323 #endif
3324
3325 printf("Before forking process PID=%d\n", getpid());
3326 ATF_REQUIRE((child = fork()) != -1);
3327 if (child == 0) {
3328 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
3329 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
3330
3331 lookup_me_fromtracee = magic_fromtracee;
3332
3333 printf("Before raising %s from child\n", strsignal(sigval));
3334 FORKEE_ASSERT(raise(sigval) == 0);
3335
3336 FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee);
3337
3338 printf("Before exiting of the child process\n");
3339 _exit(exitval);
3340 }
3341 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
3342
3343 printf("Before calling %s() for the child\n", TWAIT_FNAME);
3344 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3345
3346 validate_status_stopped(status, sigval);
3347
3348 printf("Write new lookup_me_totracee to PID=%d from tracer (PID=%d)\n",
3349 child, getpid());
3350 ATF_REQUIRE
3351 (ptrace(PT_WRITE_D, child, &lookup_me_totracee, magic_totracee)
3352 != -1);
3353
3354 printf("Read new lookup_me_fromtracee PID=%d by tracer (PID=%d)\n",
3355 child, getpid());
3356 errno = 0;
3357 lookup_me_fromtracee =
3358 ptrace(PT_READ_D, child, &lookup_me_fromtracee, 0);
3359 ATF_REQUIRE_EQ(errno, 0);
3360
3361 ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee,
3362 "got value %#x != expected %#x", lookup_me_fromtracee,
3363 magic_fromtracee);
3364
3365 printf("Before resuming the child process where it left off and "
3366 "without signal to be sent\n");
3367 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
3368
3369 printf("Before calling %s() for the child\n", TWAIT_FNAME);
3370 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3371
3372 validate_status_exited(status, exitval);
3373
3374 printf("Before calling %s() for the child\n", TWAIT_FNAME);
3375 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
3376 }
3377
3378 /* These dummy functions are used to be copied with ptrace(2) calls */
3379 static int __used
dummy_fn1(int a,int b,int c,int d)3380 dummy_fn1(int a, int b, int c, int d)
3381 {
3382
3383 a *= 1;
3384 b += 2;
3385 c -= 3;
3386 d /= 4;
3387
3388 return a + b * c - d;
3389 }
3390
3391 static int __used
dummy_fn2(int a,int b,int c,int d)3392 dummy_fn2(int a, int b, int c, int d)
3393 {
3394
3395 a *= 4;
3396 b += 3;
3397 c -= 2;
3398 d /= 1;
3399
3400 return a + b * c - d;
3401 }
3402
3403 static int __used
dummy_fn3(int a,int b,int c,int d)3404 dummy_fn3(int a, int b, int c, int d)
3405 {
3406
3407 a *= 10;
3408 b += 20;
3409 c -= 30;
3410 d /= 40;
3411
3412 return a + b * c - d;
3413 }
3414
3415 static int __used
dummy_fn4(int a,int b,int c,int d)3416 dummy_fn4(int a, int b, int c, int d)
3417 {
3418
3419 a *= 40;
3420 b += 30;
3421 c -= 20;
3422 d /= 10;
3423
3424 return a + b * c - d;
3425 }
3426
3427 ATF_TC(io_read_i1);
ATF_TC_HEAD(io_read_i1,tc)3428 ATF_TC_HEAD(io_read_i1, tc)
3429 {
3430 atf_tc_set_md_var(tc, "descr",
3431 "Verify PT_IO with PIOD_READ_I and len = sizeof(uint8_t)");
3432 }
3433
ATF_TC_BODY(io_read_i1,tc)3434 ATF_TC_BODY(io_read_i1, tc)
3435 {
3436 const int exitval = 5;
3437 const int sigval = SIGSTOP;
3438 pid_t child, wpid;
3439 uint8_t lookup_me = 0;
3440 uint8_t magic;
3441 memcpy(&magic, dummy_fn1, sizeof(magic));
3442 struct ptrace_io_desc io = {
3443 .piod_op = PIOD_READ_I,
3444 .piod_offs = dummy_fn1,
3445 .piod_addr = &lookup_me,
3446 .piod_len = sizeof(lookup_me)
3447 };
3448 #if defined(TWAIT_HAVE_STATUS)
3449 int status;
3450 #endif
3451
3452 printf("Before forking process PID=%d\n", getpid());
3453 ATF_REQUIRE((child = fork()) != -1);
3454 if (child == 0) {
3455 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
3456 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
3457
3458 printf("Before raising %s from child\n", strsignal(sigval));
3459 FORKEE_ASSERT(raise(sigval) == 0);
3460
3461 printf("Before exiting of the child process\n");
3462 _exit(exitval);
3463 }
3464 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
3465
3466 printf("Before calling %s() for the child\n", TWAIT_FNAME);
3467 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3468
3469 validate_status_stopped(status, sigval);
3470
3471 printf("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
3472 child, getpid());
3473 ATF_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
3474
3475 ATF_REQUIRE_EQ_MSG(lookup_me, magic,
3476 "got value %" PRIx8 " != expected %" PRIx8, lookup_me, magic);
3477
3478 printf("Before resuming the child process where it left off and "
3479 "without signal to be sent\n");
3480 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
3481
3482 printf("Before calling %s() for the child\n", TWAIT_FNAME);
3483 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3484
3485 validate_status_exited(status, exitval);
3486
3487 printf("Before calling %s() for the child\n", TWAIT_FNAME);
3488 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
3489 }
3490
3491 ATF_TC(io_read_i2);
ATF_TC_HEAD(io_read_i2,tc)3492 ATF_TC_HEAD(io_read_i2, tc)
3493 {
3494 atf_tc_set_md_var(tc, "descr",
3495 "Verify PT_IO with PIOD_READ_I and len = sizeof(uint16_t)");
3496 }
3497
ATF_TC_BODY(io_read_i2,tc)3498 ATF_TC_BODY(io_read_i2, tc)
3499 {
3500 const int exitval = 5;
3501 const int sigval = SIGSTOP;
3502 pid_t child, wpid;
3503 uint16_t lookup_me = 0;
3504 uint16_t magic;
3505 memcpy(&magic, dummy_fn1, sizeof(magic));
3506 struct ptrace_io_desc io = {
3507 .piod_op = PIOD_READ_I,
3508 .piod_offs = dummy_fn1,
3509 .piod_addr = &lookup_me,
3510 .piod_len = sizeof(lookup_me)
3511 };
3512 #if defined(TWAIT_HAVE_STATUS)
3513 int status;
3514 #endif
3515
3516 printf("Before forking process PID=%d\n", getpid());
3517 ATF_REQUIRE((child = fork()) != -1);
3518 if (child == 0) {
3519 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
3520 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
3521
3522 printf("Before raising %s from child\n", strsignal(sigval));
3523 FORKEE_ASSERT(raise(sigval) == 0);
3524
3525 printf("Before exiting of the child process\n");
3526 _exit(exitval);
3527 }
3528 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
3529
3530 printf("Before calling %s() for the child\n", TWAIT_FNAME);
3531 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3532
3533 validate_status_stopped(status, sigval);
3534
3535 printf("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
3536 child, getpid());
3537 ATF_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
3538
3539 ATF_REQUIRE_EQ_MSG(lookup_me, magic,
3540 "got value %" PRIx16 " != expected %" PRIx16, lookup_me, magic);
3541
3542 printf("Before resuming the child process where it left off and "
3543 "without signal to be sent\n");
3544 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
3545
3546 printf("Before calling %s() for the child\n", TWAIT_FNAME);
3547 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3548
3549 validate_status_exited(status, exitval);
3550
3551 printf("Before calling %s() for the child\n", TWAIT_FNAME);
3552 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
3553 }
3554
3555 ATF_TC(io_read_i3);
ATF_TC_HEAD(io_read_i3,tc)3556 ATF_TC_HEAD(io_read_i3, tc)
3557 {
3558 atf_tc_set_md_var(tc, "descr",
3559 "Verify PT_IO with PIOD_READ_I and len = sizeof(uint32_t)");
3560 }
3561
ATF_TC_BODY(io_read_i3,tc)3562 ATF_TC_BODY(io_read_i3, tc)
3563 {
3564 const int exitval = 5;
3565 const int sigval = SIGSTOP;
3566 pid_t child, wpid;
3567 uint32_t lookup_me = 0;
3568 uint32_t magic;
3569 memcpy(&magic, dummy_fn1, sizeof(magic));
3570 struct ptrace_io_desc io = {
3571 .piod_op = PIOD_READ_I,
3572 .piod_offs = dummy_fn1,
3573 .piod_addr = &lookup_me,
3574 .piod_len = sizeof(lookup_me)
3575 };
3576 #if defined(TWAIT_HAVE_STATUS)
3577 int status;
3578 #endif
3579
3580 printf("Before forking process PID=%d\n", getpid());
3581 ATF_REQUIRE((child = fork()) != -1);
3582 if (child == 0) {
3583 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
3584 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
3585
3586 printf("Before raising %s from child\n", strsignal(sigval));
3587 FORKEE_ASSERT(raise(sigval) == 0);
3588
3589 printf("Before exiting of the child process\n");
3590 _exit(exitval);
3591 }
3592 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
3593
3594 printf("Before calling %s() for the child\n", TWAIT_FNAME);
3595 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3596
3597 validate_status_stopped(status, sigval);
3598
3599 printf("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
3600 child, getpid());
3601 ATF_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
3602
3603 ATF_REQUIRE_EQ_MSG(lookup_me, magic,
3604 "got value %" PRIx32 " != expected %" PRIx32, lookup_me, magic);
3605
3606 printf("Before resuming the child process where it left off and "
3607 "without signal to be sent\n");
3608 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
3609
3610 printf("Before calling %s() for the child\n", TWAIT_FNAME);
3611 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3612
3613 validate_status_exited(status, exitval);
3614
3615 printf("Before calling %s() for the child\n", TWAIT_FNAME);
3616 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
3617 }
3618
3619 ATF_TC(io_read_i4);
ATF_TC_HEAD(io_read_i4,tc)3620 ATF_TC_HEAD(io_read_i4, tc)
3621 {
3622 atf_tc_set_md_var(tc, "descr",
3623 "Verify PT_IO with PIOD_READ_I and len = sizeof(uint64_t)");
3624 }
3625
ATF_TC_BODY(io_read_i4,tc)3626 ATF_TC_BODY(io_read_i4, tc)
3627 {
3628 const int exitval = 5;
3629 const int sigval = SIGSTOP;
3630 pid_t child, wpid;
3631 uint64_t lookup_me = 0;
3632 uint64_t magic;
3633 memcpy(&magic, dummy_fn1, sizeof(magic));
3634 struct ptrace_io_desc io = {
3635 .piod_op = PIOD_READ_I,
3636 .piod_offs = dummy_fn1,
3637 .piod_addr = &lookup_me,
3638 .piod_len = sizeof(lookup_me)
3639 };
3640 #if defined(TWAIT_HAVE_STATUS)
3641 int status;
3642 #endif
3643
3644 printf("Before forking process PID=%d\n", getpid());
3645 ATF_REQUIRE((child = fork()) != -1);
3646 if (child == 0) {
3647 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
3648 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
3649
3650 printf("Before raising %s from child\n", strsignal(sigval));
3651 FORKEE_ASSERT(raise(sigval) == 0);
3652
3653 printf("Before exiting of the child process\n");
3654 _exit(exitval);
3655 }
3656 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
3657
3658 printf("Before calling %s() for the child\n", TWAIT_FNAME);
3659 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3660
3661 validate_status_stopped(status, sigval);
3662
3663 printf("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
3664 child, getpid());
3665 ATF_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
3666
3667 ATF_REQUIRE_EQ_MSG(lookup_me, magic,
3668 "got value %" PRIx64 " != expected %" PRIx64, lookup_me, magic);
3669
3670 printf("Before resuming the child process where it left off and "
3671 "without signal to be sent\n");
3672 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
3673
3674 printf("Before calling %s() for the child\n", TWAIT_FNAME);
3675 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3676
3677 validate_status_exited(status, exitval);
3678
3679 printf("Before calling %s() for the child\n", TWAIT_FNAME);
3680 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
3681 }
3682
3683 ATF_TC(read_i1);
ATF_TC_HEAD(read_i1,tc)3684 ATF_TC_HEAD(read_i1, tc)
3685 {
3686 atf_tc_set_md_var(tc, "descr",
3687 "Verify PT_READ_I called once");
3688 }
3689
ATF_TC_BODY(read_i1,tc)3690 ATF_TC_BODY(read_i1, tc)
3691 {
3692 const int exitval = 5;
3693 const int sigval = SIGSTOP;
3694 pid_t child, wpid;
3695 int lookup_me = 0;
3696 int magic;
3697 memcpy(&magic, dummy_fn1, sizeof(magic));
3698 #if defined(TWAIT_HAVE_STATUS)
3699 int status;
3700 #endif
3701
3702 printf("Before forking process PID=%d\n", getpid());
3703 ATF_REQUIRE((child = fork()) != -1);
3704 if (child == 0) {
3705 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
3706 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
3707
3708 printf("Before raising %s from child\n", strsignal(sigval));
3709 FORKEE_ASSERT(raise(sigval) == 0);
3710
3711 printf("Before exiting of the child process\n");
3712 _exit(exitval);
3713 }
3714 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
3715
3716 printf("Before calling %s() for the child\n", TWAIT_FNAME);
3717 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3718
3719 validate_status_stopped(status, sigval);
3720
3721 printf("Read new lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
3722 child, getpid());
3723 errno = 0;
3724 lookup_me = ptrace(PT_READ_I, child, dummy_fn1, 0);
3725 ATF_REQUIRE_EQ(errno, 0);
3726
3727 ATF_REQUIRE_EQ_MSG(lookup_me, magic,
3728 "got value %#x != expected %#x", lookup_me, magic);
3729
3730 printf("Before resuming the child process where it left off and "
3731 "without signal to be sent\n");
3732 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
3733
3734 printf("Before calling %s() for the child\n", TWAIT_FNAME);
3735 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3736
3737 validate_status_exited(status, exitval);
3738
3739 printf("Before calling %s() for the child\n", TWAIT_FNAME);
3740 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
3741 }
3742
3743 ATF_TC(read_i2);
ATF_TC_HEAD(read_i2,tc)3744 ATF_TC_HEAD(read_i2, tc)
3745 {
3746 atf_tc_set_md_var(tc, "descr",
3747 "Verify PT_READ_I called twice");
3748 }
3749
ATF_TC_BODY(read_i2,tc)3750 ATF_TC_BODY(read_i2, tc)
3751 {
3752 const int exitval = 5;
3753 const int sigval = SIGSTOP;
3754 pid_t child, wpid;
3755 int lookup_me1 = 0;
3756 int lookup_me2 = 0;
3757 int magic1;
3758 int magic2;
3759 memcpy(&magic1, dummy_fn1, sizeof(magic1));
3760 memcpy(&magic2, dummy_fn2, sizeof(magic2));
3761 #if defined(TWAIT_HAVE_STATUS)
3762 int status;
3763 #endif
3764
3765 printf("Before forking process PID=%d\n", getpid());
3766 ATF_REQUIRE((child = fork()) != -1);
3767 if (child == 0) {
3768 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
3769 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
3770
3771 printf("Before raising %s from child\n", strsignal(sigval));
3772 FORKEE_ASSERT(raise(sigval) == 0);
3773
3774 printf("Before exiting of the child process\n");
3775 _exit(exitval);
3776 }
3777 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
3778
3779 printf("Before calling %s() for the child\n", TWAIT_FNAME);
3780 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3781
3782 validate_status_stopped(status, sigval);
3783
3784 printf("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
3785 child, getpid());
3786 errno = 0;
3787 lookup_me1 = ptrace(PT_READ_I, child, dummy_fn1, 0);
3788 ATF_REQUIRE_EQ(errno, 0);
3789
3790 ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
3791 "got value %#x != expected %#x", lookup_me1, magic1);
3792
3793 printf("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
3794 child, getpid());
3795 errno = 0;
3796 lookup_me2 = ptrace(PT_READ_I, child, dummy_fn2, 0);
3797 ATF_REQUIRE_EQ(errno, 0);
3798
3799 ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
3800 "got value %#x != expected %#x", lookup_me2, magic2);
3801
3802 printf("Before resuming the child process where it left off and "
3803 "without signal to be sent\n");
3804 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
3805
3806 printf("Before calling %s() for the child\n", TWAIT_FNAME);
3807 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3808
3809 validate_status_exited(status, exitval);
3810
3811 printf("Before calling %s() for the child\n", TWAIT_FNAME);
3812 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
3813 }
3814
3815 ATF_TC(read_i3);
ATF_TC_HEAD(read_i3,tc)3816 ATF_TC_HEAD(read_i3, tc)
3817 {
3818 atf_tc_set_md_var(tc, "descr",
3819 "Verify PT_READ_I called three times");
3820 }
3821
ATF_TC_BODY(read_i3,tc)3822 ATF_TC_BODY(read_i3, tc)
3823 {
3824 const int exitval = 5;
3825 const int sigval = SIGSTOP;
3826 pid_t child, wpid;
3827 int lookup_me1 = 0;
3828 int lookup_me2 = 0;
3829 int lookup_me3 = 0;
3830 int magic1;
3831 int magic2;
3832 int magic3;
3833 memcpy(&magic1, dummy_fn1, sizeof(magic1));
3834 memcpy(&magic2, dummy_fn2, sizeof(magic2));
3835 memcpy(&magic3, dummy_fn3, sizeof(magic3));
3836 #if defined(TWAIT_HAVE_STATUS)
3837 int status;
3838 #endif
3839
3840 printf("Before forking process PID=%d\n", getpid());
3841 ATF_REQUIRE((child = fork()) != -1);
3842 if (child == 0) {
3843 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
3844 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
3845
3846 printf("Before raising %s from child\n", strsignal(sigval));
3847 FORKEE_ASSERT(raise(sigval) == 0);
3848
3849 printf("Before exiting of the child process\n");
3850 _exit(exitval);
3851 }
3852 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
3853
3854 printf("Before calling %s() for the child\n", TWAIT_FNAME);
3855 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3856
3857 validate_status_stopped(status, sigval);
3858
3859 printf("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
3860 child, getpid());
3861 errno = 0;
3862 lookup_me1 = ptrace(PT_READ_I, child, dummy_fn1, 0);
3863 ATF_REQUIRE_EQ(errno, 0);
3864
3865 ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
3866 "got value %#x != expected %#x", lookup_me1, magic1);
3867
3868 printf("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
3869 child, getpid());
3870 errno = 0;
3871 lookup_me2 = ptrace(PT_READ_I, child, dummy_fn2, 0);
3872 ATF_REQUIRE_EQ(errno, 0);
3873
3874 ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
3875 "got value %#x != expected %#x", lookup_me2, magic2);
3876
3877 printf("Read new lookup_me3 from tracee (PID=%d) by tracer (PID=%d)\n",
3878 child, getpid());
3879 errno = 0;
3880 lookup_me3 = ptrace(PT_READ_I, child, dummy_fn3, 0);
3881 ATF_REQUIRE_EQ(errno, 0);
3882
3883 ATF_REQUIRE_EQ_MSG(lookup_me3, magic3,
3884 "got value %#x != expected %#x", lookup_me3, magic3);
3885
3886 printf("Before resuming the child process where it left off and "
3887 "without signal to be sent\n");
3888 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
3889
3890 printf("Before calling %s() for the child\n", TWAIT_FNAME);
3891 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3892
3893 validate_status_exited(status, exitval);
3894
3895 printf("Before calling %s() for the child\n", TWAIT_FNAME);
3896 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
3897 }
3898
3899 ATF_TC(read_i4);
ATF_TC_HEAD(read_i4,tc)3900 ATF_TC_HEAD(read_i4, tc)
3901 {
3902 atf_tc_set_md_var(tc, "descr",
3903 "Verify PT_READ_I called four times");
3904 }
3905
ATF_TC_BODY(read_i4,tc)3906 ATF_TC_BODY(read_i4, tc)
3907 {
3908 const int exitval = 5;
3909 const int sigval = SIGSTOP;
3910 pid_t child, wpid;
3911 int lookup_me1 = 0;
3912 int lookup_me2 = 0;
3913 int lookup_me3 = 0;
3914 int lookup_me4 = 0;
3915 int magic1;
3916 int magic2;
3917 int magic3;
3918 int magic4;
3919 memcpy(&magic1, dummy_fn1, sizeof(magic1));
3920 memcpy(&magic2, dummy_fn2, sizeof(magic2));
3921 memcpy(&magic3, dummy_fn3, sizeof(magic3));
3922 memcpy(&magic4, dummy_fn4, sizeof(magic4));
3923 #if defined(TWAIT_HAVE_STATUS)
3924 int status;
3925 #endif
3926
3927 printf("Before forking process PID=%d\n", getpid());
3928 ATF_REQUIRE((child = fork()) != -1);
3929 if (child == 0) {
3930 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
3931 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
3932
3933 printf("Before raising %s from child\n", strsignal(sigval));
3934 FORKEE_ASSERT(raise(sigval) == 0);
3935
3936 printf("Before exiting of the child process\n");
3937 _exit(exitval);
3938 }
3939 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
3940
3941 printf("Before calling %s() for the child\n", TWAIT_FNAME);
3942 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3943
3944 validate_status_stopped(status, sigval);
3945
3946 printf("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
3947 child, getpid());
3948 errno = 0;
3949 lookup_me1 = ptrace(PT_READ_I, child, dummy_fn1, 0);
3950 ATF_REQUIRE_EQ(errno, 0);
3951
3952 ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
3953 "got value %#x != expected %#x", lookup_me1, magic1);
3954
3955 printf("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
3956 child, getpid());
3957 errno = 0;
3958 lookup_me2 = ptrace(PT_READ_I, child, dummy_fn2, 0);
3959 ATF_REQUIRE_EQ(errno, 0);
3960
3961 ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
3962 "got value %#x != expected %#x", lookup_me2, magic2);
3963
3964 printf("Read new lookup_me3 from tracee (PID=%d) by tracer (PID=%d)\n",
3965 child, getpid());
3966 errno = 0;
3967 lookup_me3 = ptrace(PT_READ_I, child, dummy_fn3, 0);
3968 ATF_REQUIRE_EQ(errno, 0);
3969
3970 ATF_REQUIRE_EQ_MSG(lookup_me3, magic3,
3971 "got value %#x != expected %#x", lookup_me3, magic3);
3972
3973 printf("Read new lookup_me4 from tracee (PID=%d) by tracer (PID=%d)\n",
3974 child, getpid());
3975 errno = 0;
3976 lookup_me4 = ptrace(PT_READ_I, child, dummy_fn4, 0);
3977 ATF_REQUIRE_EQ(errno, 0);
3978
3979 ATF_REQUIRE_EQ_MSG(lookup_me4, magic4,
3980 "got value %#x != expected %#x", lookup_me4, magic4);
3981
3982 printf("Before resuming the child process where it left off and "
3983 "without signal to be sent\n");
3984 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
3985
3986 printf("Before calling %s() for the child\n", TWAIT_FNAME);
3987 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3988
3989 validate_status_exited(status, exitval);
3990
3991 printf("Before calling %s() for the child\n", TWAIT_FNAME);
3992 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
3993 }
3994
3995 #if defined(HAVE_GPREGS)
3996 ATF_TC(regs1);
ATF_TC_HEAD(regs1,tc)3997 ATF_TC_HEAD(regs1, tc)
3998 {
3999 atf_tc_set_md_var(tc, "descr",
4000 "Verify plain PT_GETREGS call without further steps");
4001 }
4002
ATF_TC_BODY(regs1,tc)4003 ATF_TC_BODY(regs1, tc)
4004 {
4005 const int exitval = 5;
4006 const int sigval = SIGSTOP;
4007 pid_t child, wpid;
4008 #if defined(TWAIT_HAVE_STATUS)
4009 int status;
4010 #endif
4011 struct reg r;
4012
4013 printf("Before forking process PID=%d\n", getpid());
4014 ATF_REQUIRE((child = fork()) != -1);
4015 if (child == 0) {
4016 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
4017 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
4018
4019 printf("Before raising %s from child\n", strsignal(sigval));
4020 FORKEE_ASSERT(raise(sigval) == 0);
4021
4022 printf("Before exiting of the child process\n");
4023 _exit(exitval);
4024 }
4025 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
4026
4027 printf("Before calling %s() for the child\n", TWAIT_FNAME);
4028 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4029
4030 validate_status_stopped(status, sigval);
4031
4032 printf("Call GETREGS for the child process\n");
4033 ATF_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
4034
4035 printf("Before resuming the child process where it left off and "
4036 "without signal to be sent\n");
4037 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4038
4039 printf("Before calling %s() for the child\n", TWAIT_FNAME);
4040 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4041
4042 validate_status_exited(status, exitval);
4043
4044 printf("Before calling %s() for the child\n", TWAIT_FNAME);
4045 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
4046 }
4047 #endif
4048
4049 #if defined(HAVE_GPREGS)
4050 ATF_TC(regs2);
ATF_TC_HEAD(regs2,tc)4051 ATF_TC_HEAD(regs2, tc)
4052 {
4053 atf_tc_set_md_var(tc, "descr",
4054 "Verify plain PT_GETREGS call and retrieve PC");
4055 }
4056
ATF_TC_BODY(regs2,tc)4057 ATF_TC_BODY(regs2, tc)
4058 {
4059 const int exitval = 5;
4060 const int sigval = SIGSTOP;
4061 pid_t child, wpid;
4062 #if defined(TWAIT_HAVE_STATUS)
4063 int status;
4064 #endif
4065 struct reg r;
4066
4067 printf("Before forking process PID=%d\n", getpid());
4068 ATF_REQUIRE((child = fork()) != -1);
4069 if (child == 0) {
4070 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
4071 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
4072
4073 printf("Before raising %s from child\n", strsignal(sigval));
4074 FORKEE_ASSERT(raise(sigval) == 0);
4075
4076 printf("Before exiting of the child process\n");
4077 _exit(exitval);
4078 }
4079 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
4080
4081 printf("Before calling %s() for the child\n", TWAIT_FNAME);
4082 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4083
4084 validate_status_stopped(status, sigval);
4085
4086 printf("Call GETREGS for the child process\n");
4087 ATF_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
4088
4089 printf("Retrieved PC=%" PRIxREGISTER "\n", PTRACE_REG_PC(&r));
4090
4091 printf("Before resuming the child process where it left off and "
4092 "without signal to be sent\n");
4093 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4094
4095 printf("Before calling %s() for the child\n", TWAIT_FNAME);
4096 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4097
4098 validate_status_exited(status, exitval);
4099
4100 printf("Before calling %s() for the child\n", TWAIT_FNAME);
4101 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
4102 }
4103 #endif
4104
4105 #if defined(HAVE_GPREGS)
4106 ATF_TC(regs3);
ATF_TC_HEAD(regs3,tc)4107 ATF_TC_HEAD(regs3, tc)
4108 {
4109 atf_tc_set_md_var(tc, "descr",
4110 "Verify plain PT_GETREGS call and retrieve SP");
4111 }
4112
ATF_TC_BODY(regs3,tc)4113 ATF_TC_BODY(regs3, tc)
4114 {
4115 const int exitval = 5;
4116 const int sigval = SIGSTOP;
4117 pid_t child, wpid;
4118 #if defined(TWAIT_HAVE_STATUS)
4119 int status;
4120 #endif
4121 struct reg r;
4122
4123 printf("Before forking process PID=%d\n", getpid());
4124 ATF_REQUIRE((child = fork()) != -1);
4125 if (child == 0) {
4126 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
4127 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
4128
4129 printf("Before raising %s from child\n", strsignal(sigval));
4130 FORKEE_ASSERT(raise(sigval) == 0);
4131
4132 printf("Before exiting of the child process\n");
4133 _exit(exitval);
4134 }
4135 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
4136
4137 printf("Before calling %s() for the child\n", TWAIT_FNAME);
4138 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4139
4140 validate_status_stopped(status, sigval);
4141
4142 printf("Call GETREGS for the child process\n");
4143 ATF_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
4144
4145 printf("Retrieved SP=%" PRIxREGISTER "\n", PTRACE_REG_SP(&r));
4146
4147 printf("Before resuming the child process where it left off and "
4148 "without signal to be sent\n");
4149 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4150
4151 printf("Before calling %s() for the child\n", TWAIT_FNAME);
4152 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4153
4154 validate_status_exited(status, exitval);
4155
4156 printf("Before calling %s() for the child\n", TWAIT_FNAME);
4157 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
4158 }
4159 #endif
4160
4161 #if defined(HAVE_GPREGS)
4162 ATF_TC(regs4);
ATF_TC_HEAD(regs4,tc)4163 ATF_TC_HEAD(regs4, tc)
4164 {
4165 atf_tc_set_md_var(tc, "descr",
4166 "Verify plain PT_GETREGS call and retrieve INTRV");
4167 }
4168
ATF_TC_BODY(regs4,tc)4169 ATF_TC_BODY(regs4, tc)
4170 {
4171 const int exitval = 5;
4172 const int sigval = SIGSTOP;
4173 pid_t child, wpid;
4174 #if defined(TWAIT_HAVE_STATUS)
4175 int status;
4176 #endif
4177 struct reg r;
4178
4179 printf("Before forking process PID=%d\n", getpid());
4180 ATF_REQUIRE((child = fork()) != -1);
4181 if (child == 0) {
4182 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
4183 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
4184
4185 printf("Before raising %s from child\n", strsignal(sigval));
4186 FORKEE_ASSERT(raise(sigval) == 0);
4187
4188 printf("Before exiting of the child process\n");
4189 _exit(exitval);
4190 }
4191 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
4192
4193 printf("Before calling %s() for the child\n", TWAIT_FNAME);
4194 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4195
4196 validate_status_stopped(status, sigval);
4197
4198 printf("Call GETREGS for the child process\n");
4199 ATF_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
4200
4201 printf("Retrieved INTRV=%" PRIxREGISTER "\n", PTRACE_REG_INTRV(&r));
4202
4203 printf("Before resuming the child process where it left off and "
4204 "without signal to be sent\n");
4205 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4206
4207 printf("Before calling %s() for the child\n", TWAIT_FNAME);
4208 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4209
4210 validate_status_exited(status, exitval);
4211
4212 printf("Before calling %s() for the child\n", TWAIT_FNAME);
4213 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
4214 }
4215 #endif
4216
4217 #if defined(HAVE_GPREGS)
4218 ATF_TC(regs5);
ATF_TC_HEAD(regs5,tc)4219 ATF_TC_HEAD(regs5, tc)
4220 {
4221 atf_tc_set_md_var(tc, "descr",
4222 "Verify PT_GETREGS and PT_SETREGS calls without changing regs");
4223 }
4224
ATF_TC_BODY(regs5,tc)4225 ATF_TC_BODY(regs5, tc)
4226 {
4227 const int exitval = 5;
4228 const int sigval = SIGSTOP;
4229 pid_t child, wpid;
4230 #if defined(TWAIT_HAVE_STATUS)
4231 int status;
4232 #endif
4233 struct reg r;
4234
4235 printf("Before forking process PID=%d\n", getpid());
4236 ATF_REQUIRE((child = fork()) != -1);
4237 if (child == 0) {
4238 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
4239 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
4240
4241 printf("Before raising %s from child\n", strsignal(sigval));
4242 FORKEE_ASSERT(raise(sigval) == 0);
4243
4244 printf("Before exiting of the child process\n");
4245 _exit(exitval);
4246 }
4247 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
4248
4249 printf("Before calling %s() for the child\n", TWAIT_FNAME);
4250 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4251
4252 validate_status_stopped(status, sigval);
4253
4254 printf("Call GETREGS for the child process\n");
4255 ATF_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
4256
4257 printf("Call SETREGS for the child process (without changed regs)\n");
4258 ATF_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
4259
4260 printf("Before resuming the child process where it left off and "
4261 "without signal to be sent\n");
4262 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4263
4264 printf("Before calling %s() for the child\n", TWAIT_FNAME);
4265 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4266
4267 validate_status_exited(status, exitval);
4268
4269 printf("Before calling %s() for the child\n", TWAIT_FNAME);
4270 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
4271 }
4272 #endif
4273
4274 #if defined(HAVE_FPREGS)
4275 ATF_TC(fpregs1);
ATF_TC_HEAD(fpregs1,tc)4276 ATF_TC_HEAD(fpregs1, tc)
4277 {
4278 atf_tc_set_md_var(tc, "descr",
4279 "Verify plain PT_GETFPREGS call without further steps");
4280 }
4281
ATF_TC_BODY(fpregs1,tc)4282 ATF_TC_BODY(fpregs1, tc)
4283 {
4284 const int exitval = 5;
4285 const int sigval = SIGSTOP;
4286 pid_t child, wpid;
4287 #if defined(TWAIT_HAVE_STATUS)
4288 int status;
4289 #endif
4290 struct fpreg r;
4291
4292 printf("Before forking process PID=%d\n", getpid());
4293 ATF_REQUIRE((child = fork()) != -1);
4294 if (child == 0) {
4295 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
4296 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
4297
4298 printf("Before raising %s from child\n", strsignal(sigval));
4299 FORKEE_ASSERT(raise(sigval) == 0);
4300
4301 printf("Before exiting of the child process\n");
4302 _exit(exitval);
4303 }
4304 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
4305
4306 printf("Before calling %s() for the child\n", TWAIT_FNAME);
4307 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4308
4309 validate_status_stopped(status, sigval);
4310
4311 printf("Call GETFPREGS for the child process\n");
4312 ATF_REQUIRE(ptrace(PT_GETFPREGS, child, &r, 0) != -1);
4313
4314 printf("Before resuming the child process where it left off and "
4315 "without signal to be sent\n");
4316 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4317
4318 printf("Before calling %s() for the child\n", TWAIT_FNAME);
4319 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4320
4321 validate_status_exited(status, exitval);
4322
4323 printf("Before calling %s() for the child\n", TWAIT_FNAME);
4324 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
4325 }
4326 #endif
4327
4328 #if defined(HAVE_FPREGS)
4329 ATF_TC(fpregs2);
ATF_TC_HEAD(fpregs2,tc)4330 ATF_TC_HEAD(fpregs2, tc)
4331 {
4332 atf_tc_set_md_var(tc, "descr",
4333 "Verify PT_GETFPREGS and PT_SETFPREGS calls without changing "
4334 "regs");
4335 }
4336
ATF_TC_BODY(fpregs2,tc)4337 ATF_TC_BODY(fpregs2, tc)
4338 {
4339 const int exitval = 5;
4340 const int sigval = SIGSTOP;
4341 pid_t child, wpid;
4342 #if defined(TWAIT_HAVE_STATUS)
4343 int status;
4344 #endif
4345 struct fpreg r;
4346
4347 printf("Before forking process PID=%d\n", getpid());
4348 ATF_REQUIRE((child = fork()) != -1);
4349 if (child == 0) {
4350 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
4351 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
4352
4353 printf("Before raising %s from child\n", strsignal(sigval));
4354 FORKEE_ASSERT(raise(sigval) == 0);
4355
4356 printf("Before exiting of the child process\n");
4357 _exit(exitval);
4358 }
4359 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
4360
4361 printf("Before calling %s() for the child\n", TWAIT_FNAME);
4362 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4363
4364 validate_status_stopped(status, sigval);
4365
4366 printf("Call GETFPREGS for the child process\n");
4367 ATF_REQUIRE(ptrace(PT_GETFPREGS, child, &r, 0) != -1);
4368
4369 printf("Call SETFPREGS for the child (without changed regs)\n");
4370 ATF_REQUIRE(ptrace(PT_SETFPREGS, child, &r, 0) != -1);
4371
4372 printf("Before resuming the child process where it left off and "
4373 "without signal to be sent\n");
4374 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4375
4376 printf("Before calling %s() for the child\n", TWAIT_FNAME);
4377 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4378
4379 validate_status_exited(status, exitval);
4380
4381 printf("Before calling %s() for the child\n", TWAIT_FNAME);
4382 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
4383 }
4384 #endif
4385
4386 #if defined(PT_STEP)
4387 ATF_TC(step1);
ATF_TC_HEAD(step1,tc)4388 ATF_TC_HEAD(step1, tc)
4389 {
4390 atf_tc_set_md_var(tc, "descr",
4391 "Verify single PT_STEP call");
4392 }
4393
ATF_TC_BODY(step1,tc)4394 ATF_TC_BODY(step1, tc)
4395 {
4396 const int exitval = 5;
4397 const int sigval = SIGSTOP;
4398 pid_t child, wpid;
4399 #if defined(TWAIT_HAVE_STATUS)
4400 int status;
4401 #endif
4402 int happy;
4403
4404 printf("Before forking process PID=%d\n", getpid());
4405 ATF_REQUIRE((child = fork()) != -1);
4406 if (child == 0) {
4407 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
4408 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
4409
4410 happy = check_happy(100);
4411
4412 printf("Before raising %s from child\n", strsignal(sigval));
4413 FORKEE_ASSERT(raise(sigval) == 0);
4414
4415 FORKEE_ASSERT_EQ(happy, check_happy(100));
4416
4417 printf("Before exiting of the child process\n");
4418 _exit(exitval);
4419 }
4420 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
4421
4422 printf("Before calling %s() for the child\n", TWAIT_FNAME);
4423 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4424
4425 validate_status_stopped(status, sigval);
4426
4427 printf("Before resuming the child process where it left off and "
4428 "without signal to be sent (use PT_STEP)\n");
4429 ATF_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0) != -1);
4430
4431 printf("Before calling %s() for the child\n", TWAIT_FNAME);
4432 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4433
4434 validate_status_stopped(status, SIGTRAP);
4435
4436 printf("Before resuming the child process where it left off and "
4437 "without signal to be sent\n");
4438 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4439
4440 printf("Before calling %s() for the child\n", TWAIT_FNAME);
4441 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4442
4443 validate_status_exited(status, exitval);
4444
4445 printf("Before calling %s() for the child\n", TWAIT_FNAME);
4446 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
4447 }
4448 #endif
4449
4450 #if defined(PT_STEP)
4451 ATF_TC(step2);
ATF_TC_HEAD(step2,tc)4452 ATF_TC_HEAD(step2, tc)
4453 {
4454 atf_tc_set_md_var(tc, "descr",
4455 "Verify PT_STEP called twice");
4456 }
4457
ATF_TC_BODY(step2,tc)4458 ATF_TC_BODY(step2, tc)
4459 {
4460 const int exitval = 5;
4461 const int sigval = SIGSTOP;
4462 pid_t child, wpid;
4463 #if defined(TWAIT_HAVE_STATUS)
4464 int status;
4465 #endif
4466 int happy;
4467 int N = 2;
4468
4469 printf("Before forking process PID=%d\n", getpid());
4470 ATF_REQUIRE((child = fork()) != -1);
4471 if (child == 0) {
4472 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
4473 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
4474
4475 happy = check_happy(999);
4476
4477 printf("Before raising %s from child\n", strsignal(sigval));
4478 FORKEE_ASSERT(raise(sigval) == 0);
4479
4480 FORKEE_ASSERT_EQ(happy, check_happy(999));
4481
4482 printf("Before exiting of the child process\n");
4483 _exit(exitval);
4484 }
4485 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
4486
4487 printf("Before calling %s() for the child\n", TWAIT_FNAME);
4488 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4489
4490 validate_status_stopped(status, sigval);
4491
4492 while (N --> 0) {
4493 printf("Before resuming the child process where it left off "
4494 "and without signal to be sent (use PT_STEP)\n");
4495 ATF_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0) != -1);
4496
4497 printf("Before calling %s() for the child\n", TWAIT_FNAME);
4498 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
4499 child);
4500
4501 validate_status_stopped(status, SIGTRAP);
4502 }
4503
4504 printf("Before resuming the child process where it left off and "
4505 "without signal to be sent\n");
4506 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4507
4508 printf("Before calling %s() for the child\n", TWAIT_FNAME);
4509 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4510
4511 validate_status_exited(status, exitval);
4512
4513 printf("Before calling %s() for the child\n", TWAIT_FNAME);
4514 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
4515 }
4516 #endif
4517
4518 #if defined(PT_STEP)
4519 ATF_TC(step3);
ATF_TC_HEAD(step3,tc)4520 ATF_TC_HEAD(step3, tc)
4521 {
4522 atf_tc_set_md_var(tc, "descr",
4523 "Verify PT_STEP called three times");
4524 }
4525
ATF_TC_BODY(step3,tc)4526 ATF_TC_BODY(step3, tc)
4527 {
4528 const int exitval = 5;
4529 const int sigval = SIGSTOP;
4530 pid_t child, wpid;
4531 #if defined(TWAIT_HAVE_STATUS)
4532 int status;
4533 #endif
4534 int happy;
4535 int N = 3;
4536
4537 printf("Before forking process PID=%d\n", getpid());
4538 ATF_REQUIRE((child = fork()) != -1);
4539 if (child == 0) {
4540 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
4541 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
4542
4543 happy = check_happy(999);
4544
4545 printf("Before raising %s from child\n", strsignal(sigval));
4546 FORKEE_ASSERT(raise(sigval) == 0);
4547
4548 FORKEE_ASSERT_EQ(happy, check_happy(999));
4549
4550 printf("Before exiting of the child process\n");
4551 _exit(exitval);
4552 }
4553 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
4554
4555 printf("Before calling %s() for the child\n", TWAIT_FNAME);
4556 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4557
4558 validate_status_stopped(status, sigval);
4559
4560 while (N --> 0) {
4561 printf("Before resuming the child process where it left off "
4562 "and without signal to be sent (use PT_STEP)\n");
4563 ATF_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0) != -1);
4564
4565 printf("Before calling %s() for the child\n", TWAIT_FNAME);
4566 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
4567 child);
4568
4569 validate_status_stopped(status, SIGTRAP);
4570 }
4571
4572 printf("Before resuming the child process where it left off and "
4573 "without signal to be sent\n");
4574 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4575
4576 printf("Before calling %s() for the child\n", TWAIT_FNAME);
4577 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4578
4579 validate_status_exited(status, exitval);
4580
4581 printf("Before calling %s() for the child\n", TWAIT_FNAME);
4582 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
4583 }
4584 #endif
4585
4586 #if defined(PT_STEP)
4587 ATF_TC(step4);
ATF_TC_HEAD(step4,tc)4588 ATF_TC_HEAD(step4, tc)
4589 {
4590 atf_tc_set_md_var(tc, "descr",
4591 "Verify PT_STEP called four times");
4592 }
4593
ATF_TC_BODY(step4,tc)4594 ATF_TC_BODY(step4, tc)
4595 {
4596 const int exitval = 5;
4597 const int sigval = SIGSTOP;
4598 pid_t child, wpid;
4599 #if defined(TWAIT_HAVE_STATUS)
4600 int status;
4601 #endif
4602 int happy;
4603 int N = 4;
4604
4605 printf("Before forking process PID=%d\n", getpid());
4606 ATF_REQUIRE((child = fork()) != -1);
4607 if (child == 0) {
4608 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
4609 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
4610
4611 happy = check_happy(999);
4612
4613 printf("Before raising %s from child\n", strsignal(sigval));
4614 FORKEE_ASSERT(raise(sigval) == 0);
4615
4616 FORKEE_ASSERT_EQ(happy, check_happy(999));
4617
4618 printf("Before exiting of the child process\n");
4619 _exit(exitval);
4620 }
4621 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
4622
4623 printf("Before calling %s() for the child\n", TWAIT_FNAME);
4624 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4625
4626 validate_status_stopped(status, sigval);
4627
4628 while (N --> 0) {
4629 printf("Before resuming the child process where it left off "
4630 "and without signal to be sent (use PT_STEP)\n");
4631 ATF_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0) != -1);
4632
4633 printf("Before calling %s() for the child\n", TWAIT_FNAME);
4634 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
4635 child);
4636
4637 validate_status_stopped(status, SIGTRAP);
4638 }
4639
4640 printf("Before resuming the child process where it left off and "
4641 "without signal to be sent\n");
4642 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4643
4644 printf("Before calling %s() for the child\n", TWAIT_FNAME);
4645 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4646
4647 validate_status_exited(status, exitval);
4648
4649 printf("Before calling %s() for the child\n", TWAIT_FNAME);
4650 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
4651 }
4652 #endif
4653
4654 ATF_TC(kill1);
ATF_TC_HEAD(kill1,tc)4655 ATF_TC_HEAD(kill1, tc)
4656 {
4657 atf_tc_set_md_var(tc, "descr",
4658 "Verify that PT_CONTINUE with SIGKILL terminates child");
4659 }
4660
ATF_TC_BODY(kill1,tc)4661 ATF_TC_BODY(kill1, tc)
4662 {
4663 const int sigval = SIGSTOP, sigsent = SIGKILL;
4664 pid_t child, wpid;
4665 #if defined(TWAIT_HAVE_STATUS)
4666 int status;
4667 #endif
4668
4669 printf("Before forking process PID=%d\n", getpid());
4670 ATF_REQUIRE((child = fork()) != -1);
4671 if (child == 0) {
4672 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
4673 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
4674
4675 printf("Before raising %s from child\n", strsignal(sigval));
4676 FORKEE_ASSERT(raise(sigval) == 0);
4677
4678 /* NOTREACHED */
4679 FORKEE_ASSERTX(0 &&
4680 "Child should be terminated by a signal from its parent");
4681 }
4682 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
4683
4684 printf("Before calling %s() for the child\n", TWAIT_FNAME);
4685 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4686
4687 validate_status_stopped(status, sigval);
4688
4689 printf("Before resuming the child process where it left off and "
4690 "without signal to be sent\n");
4691 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1);
4692
4693 printf("Before calling %s() for the child\n", TWAIT_FNAME);
4694 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4695
4696 validate_status_signaled(status, sigsent, 0);
4697
4698 printf("Before calling %s() for the child\n", TWAIT_FNAME);
4699 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
4700 }
4701
4702 ATF_TC(kill2);
ATF_TC_HEAD(kill2,tc)4703 ATF_TC_HEAD(kill2, tc)
4704 {
4705 atf_tc_set_md_var(tc, "descr",
4706 "Verify that PT_KILL terminates child");
4707 }
4708
ATF_TC_BODY(kill2,tc)4709 ATF_TC_BODY(kill2, tc)
4710 {
4711 const int sigval = SIGSTOP;
4712 pid_t child, wpid;
4713 #if defined(TWAIT_HAVE_STATUS)
4714 int status;
4715 #endif
4716
4717 printf("Before forking process PID=%d\n", getpid());
4718 ATF_REQUIRE((child = fork()) != -1);
4719 if (child == 0) {
4720 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
4721 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
4722
4723 printf("Before raising %s from child\n", strsignal(sigval));
4724 FORKEE_ASSERT(raise(sigval) == 0);
4725
4726 /* NOTREACHED */
4727 FORKEE_ASSERTX(0 &&
4728 "Child should be terminated by a signal from its parent");
4729 }
4730 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
4731
4732 printf("Before calling %s() for the child\n", TWAIT_FNAME);
4733 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4734
4735 validate_status_stopped(status, sigval);
4736
4737 printf("Before resuming the child process where it left off and "
4738 "without signal to be sent\n");
4739 ATF_REQUIRE(ptrace(PT_KILL, child, (void*)1, 0) != -1);
4740
4741 printf("Before calling %s() for the child\n", TWAIT_FNAME);
4742 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4743
4744 validate_status_signaled(status, SIGKILL, 0);
4745
4746 printf("Before calling %s() for the child\n", TWAIT_FNAME);
4747 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
4748 }
4749
4750 ATF_TC(lwpinfo1);
ATF_TC_HEAD(lwpinfo1,tc)4751 ATF_TC_HEAD(lwpinfo1, tc)
4752 {
4753 atf_tc_set_md_var(tc, "descr",
4754 "Verify basic LWPINFO call for single thread (PT_TRACE_ME)");
4755 }
4756
ATF_TC_BODY(lwpinfo1,tc)4757 ATF_TC_BODY(lwpinfo1, tc)
4758 {
4759 const int exitval = 5;
4760 const int sigval = SIGSTOP;
4761 pid_t child, wpid;
4762 #if defined(TWAIT_HAVE_STATUS)
4763 int status;
4764 #endif
4765 struct ptrace_lwpinfo info = {0, 0};
4766
4767 printf("Before forking process PID=%d\n", getpid());
4768 ATF_REQUIRE((child = fork()) != -1);
4769 if (child == 0) {
4770 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
4771 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
4772
4773 printf("Before raising %s from child\n", strsignal(sigval));
4774 FORKEE_ASSERT(raise(sigval) == 0);
4775
4776 printf("Before exiting of the child process\n");
4777 _exit(exitval);
4778 }
4779 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
4780
4781 printf("Before calling %s() for the child\n", TWAIT_FNAME);
4782 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4783
4784 validate_status_stopped(status, sigval);
4785
4786 printf("Before calling ptrace(2) with PT_LWPINFO for child\n");
4787 ATF_REQUIRE(ptrace(PT_LWPINFO, child, &info, sizeof(info)) != -1);
4788
4789 printf("Assert that there exists a thread\n");
4790 ATF_REQUIRE(info.pl_lwpid > 0);
4791
4792 printf("Assert that lwp thread %d received event PL_EVENT_SIGNAL\n",
4793 info.pl_lwpid);
4794 ATF_REQUIRE_EQ_MSG(info.pl_event, PL_EVENT_SIGNAL,
4795 "Received event %d != expected event %d",
4796 info.pl_event, PL_EVENT_SIGNAL);
4797
4798 printf("Before calling ptrace(2) with PT_LWPINFO for child\n");
4799 ATF_REQUIRE(ptrace(PT_LWPINFO, child, &info, sizeof(info)) != -1);
4800
4801 printf("Assert that there are no more lwp threads in child\n");
4802 ATF_REQUIRE_EQ(info.pl_lwpid, 0);
4803
4804 printf("Before resuming the child process where it left off and "
4805 "without signal to be sent\n");
4806 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4807
4808 printf("Before calling %s() for the child\n", TWAIT_FNAME);
4809 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4810
4811 validate_status_exited(status, exitval);
4812
4813 printf("Before calling %s() for the child\n", TWAIT_FNAME);
4814 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
4815 }
4816
4817 #if defined(TWAIT_HAVE_PID)
4818 ATF_TC(lwpinfo2);
ATF_TC_HEAD(lwpinfo2,tc)4819 ATF_TC_HEAD(lwpinfo2, tc)
4820 {
4821 atf_tc_set_md_var(tc, "descr",
4822 "Verify basic LWPINFO call for single thread (PT_ATTACH from "
4823 "tracer)");
4824 }
4825
ATF_TC_BODY(lwpinfo2,tc)4826 ATF_TC_BODY(lwpinfo2, tc)
4827 {
4828 struct msg_fds parent_tracee, parent_tracer;
4829 const int exitval_tracee = 5;
4830 const int exitval_tracer = 10;
4831 pid_t tracee, tracer, wpid;
4832 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
4833 #if defined(TWAIT_HAVE_STATUS)
4834 int status;
4835 #endif
4836 struct ptrace_lwpinfo info = {0, 0};
4837
4838 printf("Spawn tracee\n");
4839 ATF_REQUIRE(msg_open(&parent_tracee) == 0);
4840 ATF_REQUIRE(msg_open(&parent_tracer) == 0);
4841 tracee = atf_utils_fork();
4842 if (tracee == 0) {
4843
4844 /* Wait for message from the parent */
4845 CHILD_TO_PARENT("tracee ready", parent_tracee, msg);
4846 CHILD_FROM_PARENT("tracee exit", parent_tracee, msg);
4847
4848 _exit(exitval_tracee);
4849 }
4850 PARENT_FROM_CHILD("tracee ready", parent_tracee, msg);
4851
4852 printf("Spawn debugger\n");
4853 tracer = atf_utils_fork();
4854 if (tracer == 0) {
4855 /* No IPC to communicate with the child */
4856 printf("Before calling PT_ATTACH from tracee %d\n", getpid());
4857 FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
4858
4859 /* Wait for tracee and assert that it was stopped w/ SIGSTOP */
4860 FORKEE_REQUIRE_SUCCESS(
4861 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
4862
4863 forkee_status_stopped(status, SIGSTOP);
4864
4865 printf("Before calling ptrace(2) with PT_LWPINFO for child\n");
4866 FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &info, sizeof(info))
4867 != -1);
4868
4869 printf("Assert that there exists a thread\n");
4870 FORKEE_ASSERTX(info.pl_lwpid > 0);
4871
4872 printf("Assert that lwp thread %d received event "
4873 "PL_EVENT_SIGNAL\n", info.pl_lwpid);
4874 FORKEE_ASSERT_EQ(info.pl_event, PL_EVENT_SIGNAL);
4875
4876 printf("Before calling ptrace(2) with PT_LWPINFO for child\n");
4877 FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &info, sizeof(info))
4878 != -1);
4879
4880 printf("Assert that there are no more lwp threads in child\n");
4881 FORKEE_ASSERTX(info.pl_lwpid == 0);
4882
4883 /* Resume tracee with PT_CONTINUE */
4884 FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
4885
4886 /* Inform parent that tracer has attached to tracee */
4887 CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
4888 /* Wait for parent */
4889 CHILD_FROM_PARENT("tracer wait", parent_tracer, msg);
4890
4891 /* Wait for tracee and assert that it exited */
4892 FORKEE_REQUIRE_SUCCESS(
4893 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
4894
4895 forkee_status_exited(status, exitval_tracee);
4896
4897 printf("Before exiting of the tracer process\n");
4898 _exit(exitval_tracer);
4899 }
4900
4901 printf("Wait for the tracer to attach to the tracee\n");
4902 PARENT_FROM_CHILD("tracer ready", parent_tracer, msg);
4903
4904 printf("Resume the tracee and let it exit\n");
4905 PARENT_TO_CHILD("tracee exit", parent_tracee, msg);
4906
4907 printf("Detect that tracee is zombie\n");
4908 await_zombie(tracee);
4909
4910 printf("Assert that there is no status about tracee - "
4911 "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
4912 TWAIT_REQUIRE_SUCCESS(
4913 wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
4914
4915 printf("Resume the tracer and let it detect exited tracee\n");
4916 PARENT_TO_CHILD("tracer wait", parent_tracer, msg);
4917
4918 printf("Wait for tracer to finish its job and exit - calling %s()\n",
4919 TWAIT_FNAME);
4920 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
4921 tracer);
4922
4923 validate_status_exited(status, exitval_tracer);
4924
4925 printf("Wait for tracee to finish its job and exit - calling %s()\n",
4926 TWAIT_FNAME);
4927 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
4928 tracee);
4929
4930 validate_status_exited(status, exitval_tracee);
4931
4932 msg_close(&parent_tracer);
4933 msg_close(&parent_tracee);
4934 }
4935 #endif
4936
4937 ATF_TC(siginfo1);
ATF_TC_HEAD(siginfo1,tc)4938 ATF_TC_HEAD(siginfo1, tc)
4939 {
4940 atf_tc_set_md_var(tc, "descr",
4941 "Verify basic PT_GET_SIGINFO call for SIGTRAP from tracee");
4942 }
4943
ATF_TC_BODY(siginfo1,tc)4944 ATF_TC_BODY(siginfo1, tc)
4945 {
4946 const int exitval = 5;
4947 const int sigval = SIGTRAP;
4948 pid_t child, wpid;
4949 #if defined(TWAIT_HAVE_STATUS)
4950 int status;
4951 #endif
4952 struct ptrace_siginfo info;
4953 memset(&info, 0, sizeof(info));
4954
4955 printf("Before forking process PID=%d\n", getpid());
4956 ATF_REQUIRE((child = fork()) != -1);
4957 if (child == 0) {
4958 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
4959 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
4960
4961 printf("Before raising %s from child\n", strsignal(sigval));
4962 FORKEE_ASSERT(raise(sigval) == 0);
4963
4964 printf("Before exiting of the child process\n");
4965 _exit(exitval);
4966 }
4967 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
4968
4969 printf("Before calling %s() for the child\n", TWAIT_FNAME);
4970 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4971
4972 validate_status_stopped(status, sigval);
4973
4974 printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
4975 ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
4976
4977 printf("Signal traced to lwpid=%d\n", info.psi_lwpid);
4978 printf("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
4979 info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
4980 info.psi_siginfo.si_errno);
4981
4982 printf("Before resuming the child process where it left off and "
4983 "without signal to be sent\n");
4984 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4985
4986 printf("Before calling %s() for the child\n", TWAIT_FNAME);
4987 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4988
4989 validate_status_exited(status, exitval);
4990
4991 printf("Before calling %s() for the child\n", TWAIT_FNAME);
4992 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
4993 }
4994
4995 ATF_TC(siginfo2);
ATF_TC_HEAD(siginfo2,tc)4996 ATF_TC_HEAD(siginfo2, tc)
4997 {
4998 atf_tc_set_md_var(tc, "descr",
4999 "Verify basic PT_GET_SIGINFO and PT_SET_SIGINFO calls without "
5000 "modification of SIGINT from tracee");
5001 }
5002
5003 static int siginfo2_caught = 0;
5004
5005 static void
siginfo2_sighandler(int sig)5006 siginfo2_sighandler(int sig)
5007 {
5008 FORKEE_ASSERT_EQ(sig, SIGINT);
5009
5010 ++siginfo2_caught;
5011 }
5012
ATF_TC_BODY(siginfo2,tc)5013 ATF_TC_BODY(siginfo2, tc)
5014 {
5015 const int exitval = 5;
5016 const int sigval = SIGINT;
5017 pid_t child, wpid;
5018 struct sigaction sa;
5019 #if defined(TWAIT_HAVE_STATUS)
5020 int status;
5021 #endif
5022 struct ptrace_siginfo info;
5023 memset(&info, 0, sizeof(info));
5024
5025 printf("Before forking process PID=%d\n", getpid());
5026 ATF_REQUIRE((child = fork()) != -1);
5027 if (child == 0) {
5028 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
5029 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
5030
5031 sa.sa_handler = siginfo2_sighandler;
5032 sa.sa_flags = SA_SIGINFO;
5033 sigemptyset(&sa.sa_mask);
5034
5035 FORKEE_ASSERT(sigaction(sigval, &sa, NULL) != -1);
5036
5037 printf("Before raising %s from child\n", strsignal(sigval));
5038 FORKEE_ASSERT(raise(sigval) == 0);
5039
5040 FORKEE_ASSERT_EQ(siginfo2_caught, 1);
5041
5042 printf("Before exiting of the child process\n");
5043 _exit(exitval);
5044 }
5045 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
5046
5047 printf("Before calling %s() for the child\n", TWAIT_FNAME);
5048 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5049
5050 validate_status_stopped(status, sigval);
5051
5052 printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
5053 ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
5054
5055 printf("Signal traced to lwpid=%d\n", info.psi_lwpid);
5056 printf("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
5057 info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
5058 info.psi_siginfo.si_errno);
5059
5060 printf("Before calling ptrace(2) with PT_SET_SIGINFO for child\n");
5061 ATF_REQUIRE(ptrace(PT_SET_SIGINFO, child, &info, sizeof(info)) != -1);
5062
5063 printf("Before resuming the child process where it left off and "
5064 "without signal to be sent\n");
5065 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigval) != -1);
5066
5067 printf("Before calling %s() for the child\n", TWAIT_FNAME);
5068 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5069
5070 validate_status_exited(status, exitval);
5071
5072 printf("Before calling %s() for the child\n", TWAIT_FNAME);
5073 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
5074 }
5075
5076 ATF_TC(siginfo3);
ATF_TC_HEAD(siginfo3,tc)5077 ATF_TC_HEAD(siginfo3, tc)
5078 {
5079 atf_tc_set_md_var(tc, "descr",
5080 "Verify basic PT_GET_SIGINFO and PT_SET_SIGINFO calls with "
5081 "setting signal to new value");
5082 }
5083
5084 static int siginfo3_caught = 0;
5085
5086 static void
siginfo3_sigaction(int sig,siginfo_t * info,void * ctx)5087 siginfo3_sigaction(int sig, siginfo_t *info, void *ctx)
5088 {
5089 FORKEE_ASSERT_EQ(sig, SIGTRAP);
5090
5091 FORKEE_ASSERT_EQ(info->si_signo, SIGTRAP);
5092 FORKEE_ASSERT_EQ(info->si_code, TRAP_BRKPT);
5093
5094 ++siginfo3_caught;
5095 }
5096
ATF_TC_BODY(siginfo3,tc)5097 ATF_TC_BODY(siginfo3, tc)
5098 {
5099 const int exitval = 5;
5100 const int sigval = SIGINT;
5101 const int sigfaked = SIGTRAP;
5102 const int sicodefaked = TRAP_BRKPT;
5103 pid_t child, wpid;
5104 struct sigaction sa;
5105 #if defined(TWAIT_HAVE_STATUS)
5106 int status;
5107 #endif
5108 struct ptrace_siginfo info;
5109 memset(&info, 0, sizeof(info));
5110
5111 printf("Before forking process PID=%d\n", getpid());
5112 ATF_REQUIRE((child = fork()) != -1);
5113 if (child == 0) {
5114 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
5115 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
5116
5117 sa.sa_sigaction = siginfo3_sigaction;
5118 sa.sa_flags = SA_SIGINFO;
5119 sigemptyset(&sa.sa_mask);
5120
5121 FORKEE_ASSERT(sigaction(sigfaked, &sa, NULL) != -1);
5122
5123 printf("Before raising %s from child\n", strsignal(sigval));
5124 FORKEE_ASSERT(raise(sigval) == 0);
5125
5126 FORKEE_ASSERT_EQ(siginfo3_caught, 1);
5127
5128 printf("Before exiting of the child process\n");
5129 _exit(exitval);
5130 }
5131 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
5132
5133 printf("Before calling %s() for the child\n", TWAIT_FNAME);
5134 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5135
5136 validate_status_stopped(status, sigval);
5137
5138 printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
5139 ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
5140
5141 printf("Signal traced to lwpid=%d\n", info.psi_lwpid);
5142 printf("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
5143 info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
5144 info.psi_siginfo.si_errno);
5145
5146 printf("Before setting new faked signal to signo=%d si_code=%d\n",
5147 sigfaked, sicodefaked);
5148 info.psi_siginfo.si_signo = sigfaked;
5149 info.psi_siginfo.si_code = sicodefaked;
5150
5151 printf("Before calling ptrace(2) with PT_SET_SIGINFO for child\n");
5152 ATF_REQUIRE(ptrace(PT_SET_SIGINFO, child, &info, sizeof(info)) != -1);
5153
5154 printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
5155 ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
5156
5157 printf("Before checking siginfo_t\n");
5158 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigfaked);
5159 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, sicodefaked);
5160
5161 printf("Before resuming the child process where it left off and "
5162 "without signal to be sent\n");
5163 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigfaked) != -1);
5164
5165 printf("Before calling %s() for the child\n", TWAIT_FNAME);
5166 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5167
5168 validate_status_exited(status, exitval);
5169
5170 printf("Before calling %s() for the child\n", TWAIT_FNAME);
5171 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
5172 }
5173
5174 ATF_TC(siginfo4);
ATF_TC_HEAD(siginfo4,tc)5175 ATF_TC_HEAD(siginfo4, tc)
5176 {
5177 atf_tc_set_md_var(tc, "descr",
5178 "Detect SIGTRAP TRAP_EXEC from tracee");
5179 }
5180
ATF_TC_BODY(siginfo4,tc)5181 ATF_TC_BODY(siginfo4, tc)
5182 {
5183 const int sigval = SIGTRAP;
5184 pid_t child, wpid;
5185 #if defined(TWAIT_HAVE_STATUS)
5186 int status;
5187 #endif
5188
5189 struct ptrace_siginfo info;
5190 memset(&info, 0, sizeof(info));
5191
5192 printf("Before forking process PID=%d\n", getpid());
5193 ATF_REQUIRE((child = fork()) != -1);
5194 if (child == 0) {
5195 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
5196 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
5197
5198 printf("Before calling execve(2) from child\n");
5199 execlp("/bin/echo", "/bin/echo", NULL);
5200
5201 FORKEE_ASSERT(0 && "Not reached");
5202 }
5203 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
5204
5205 printf("Before calling %s() for the child\n", TWAIT_FNAME);
5206 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5207
5208 validate_status_stopped(status, sigval);
5209
5210 printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
5211 ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
5212
5213 printf("Signal traced to lwpid=%d\n", info.psi_lwpid);
5214 printf("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
5215 info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
5216 info.psi_siginfo.si_errno);
5217
5218 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
5219 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC);
5220
5221 printf("Before resuming the child process where it left off and "
5222 "without signal to be sent\n");
5223 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5224
5225 printf("Before calling %s() for the child\n", TWAIT_FNAME);
5226 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5227
5228 printf("Before calling %s() for the child\n", TWAIT_FNAME);
5229 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
5230 }
5231
5232 #if defined(TWAIT_HAVE_PID)
5233 ATF_TC(siginfo5);
ATF_TC_HEAD(siginfo5,tc)5234 ATF_TC_HEAD(siginfo5, tc)
5235 {
5236 atf_tc_set_md_var(tc, "descr",
5237 "Verify that fork(2) is intercepted by ptrace(2) with EVENT_MASK "
5238 "set to PTRACE_FORK and reports correct signal information");
5239 }
5240
ATF_TC_BODY(siginfo5,tc)5241 ATF_TC_BODY(siginfo5, tc)
5242 {
5243 const int exitval = 5;
5244 const int exitval2 = 15;
5245 const int sigval = SIGSTOP;
5246 pid_t child, child2, wpid;
5247 #if defined(TWAIT_HAVE_STATUS)
5248 int status;
5249 #endif
5250 ptrace_state_t state;
5251 const int slen = sizeof(state);
5252 ptrace_event_t event;
5253 const int elen = sizeof(event);
5254 struct ptrace_siginfo info;
5255
5256 memset(&info, 0, sizeof(info));
5257
5258 printf("Before forking process PID=%d\n", getpid());
5259 ATF_REQUIRE((child = fork()) != -1);
5260 if (child == 0) {
5261 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
5262 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
5263
5264 printf("Before raising %s from child\n", strsignal(sigval));
5265 FORKEE_ASSERT(raise(sigval) == 0);
5266
5267 FORKEE_ASSERT((child2 = fork()) != 1);
5268
5269 if (child2 == 0)
5270 _exit(exitval2);
5271
5272 FORKEE_REQUIRE_SUCCESS
5273 (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
5274
5275 forkee_status_exited(status, exitval2);
5276
5277 printf("Before exiting of the child process\n");
5278 _exit(exitval);
5279 }
5280 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
5281
5282 printf("Before calling %s() for the child\n", TWAIT_FNAME);
5283 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5284
5285 validate_status_stopped(status, sigval);
5286
5287 printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
5288 ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
5289
5290 printf("Before checking siginfo_t\n");
5291 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
5292 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
5293
5294 printf("Enable PTRACE_FORK in EVENT_MASK for the child %d\n", child);
5295 event.pe_set_event = PTRACE_FORK;
5296 ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
5297
5298 printf("Before resuming the child process where it left off and "
5299 "without signal to be sent\n");
5300 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5301
5302 printf("Before calling %s() for the child %d\n", TWAIT_FNAME, child);
5303 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5304
5305 validate_status_stopped(status, SIGTRAP);
5306
5307 printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
5308 ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
5309
5310 printf("Before checking siginfo_t\n");
5311 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
5312 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_CHLD);
5313
5314 ATF_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
5315 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
5316
5317 child2 = state.pe_other_pid;
5318 printf("Reported PTRACE_FORK event with forkee %d\n", child2);
5319
5320 printf("Before calling %s() for the forkee %d of the child %d\n",
5321 TWAIT_FNAME, child2, child);
5322 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
5323 child2);
5324
5325 validate_status_stopped(status, SIGTRAP);
5326
5327 printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
5328 ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
5329
5330 printf("Before checking siginfo_t\n");
5331 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
5332 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_CHLD);
5333
5334 ATF_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
5335 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
5336 ATF_REQUIRE_EQ(state.pe_other_pid, child);
5337
5338 printf("Before resuming the forkee process where it left off and "
5339 "without signal to be sent\n");
5340 ATF_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
5341
5342 printf("Before resuming the child process where it left off and "
5343 "without signal to be sent\n");
5344 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5345
5346 printf("Before calling %s() for the forkee - expected exited\n",
5347 TWAIT_FNAME);
5348 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
5349 child2);
5350
5351 validate_status_exited(status, exitval2);
5352
5353 printf("Before calling %s() for the forkee - expected no process\n",
5354 TWAIT_FNAME);
5355 TWAIT_REQUIRE_FAILURE(ECHILD,
5356 wpid = TWAIT_GENERIC(child2, &status, 0));
5357
5358 printf("Before calling %s() for the child - expected stopped "
5359 "SIGCHLD\n", TWAIT_FNAME);
5360 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5361
5362 validate_status_stopped(status, SIGCHLD);
5363
5364 printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
5365 ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
5366
5367 printf("Before checking siginfo_t\n");
5368 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGCHLD);
5369 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, CLD_EXITED);
5370
5371 printf("Before resuming the child process where it left off and "
5372 "without signal to be sent\n");
5373 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5374
5375 printf("Before calling %s() for the child - expected exited\n",
5376 TWAIT_FNAME);
5377 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5378
5379 validate_status_exited(status, exitval);
5380
5381 printf("Before calling %s() for the child - expected no process\n",
5382 TWAIT_FNAME);
5383 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
5384 }
5385 #endif
5386
5387 #if defined(PT_STEP)
5388 ATF_TC(siginfo6);
ATF_TC_HEAD(siginfo6,tc)5389 ATF_TC_HEAD(siginfo6, tc)
5390 {
5391 atf_tc_set_md_var(tc, "descr",
5392 "Verify single PT_STEP call with signal information check");
5393 }
5394
ATF_TC_BODY(siginfo6,tc)5395 ATF_TC_BODY(siginfo6, tc)
5396 {
5397 const int exitval = 5;
5398 const int sigval = SIGSTOP;
5399 pid_t child, wpid;
5400 #if defined(TWAIT_HAVE_STATUS)
5401 int status;
5402 #endif
5403 int happy;
5404 struct ptrace_siginfo info;
5405
5406 memset(&info, 0, sizeof(info));
5407
5408 printf("Before forking process PID=%d\n", getpid());
5409 ATF_REQUIRE((child = fork()) != -1);
5410 if (child == 0) {
5411 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
5412 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
5413
5414 happy = check_happy(100);
5415
5416 printf("Before raising %s from child\n", strsignal(sigval));
5417 FORKEE_ASSERT(raise(sigval) == 0);
5418
5419 FORKEE_ASSERT_EQ(happy, check_happy(100));
5420
5421 printf("Before exiting of the child process\n");
5422 _exit(exitval);
5423 }
5424 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
5425
5426 printf("Before calling %s() for the child\n", TWAIT_FNAME);
5427 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5428
5429 validate_status_stopped(status, sigval);
5430
5431 printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
5432 ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
5433
5434 printf("Before checking siginfo_t\n");
5435 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
5436 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
5437
5438 printf("Before resuming the child process where it left off and "
5439 "without signal to be sent (use PT_STEP)\n");
5440 ATF_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0) != -1);
5441
5442 printf("Before calling %s() for the child\n", TWAIT_FNAME);
5443 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5444
5445 validate_status_stopped(status, SIGTRAP);
5446
5447 printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
5448 ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
5449
5450 printf("Before checking siginfo_t\n");
5451 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
5452 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_TRACE);
5453
5454 printf("Before resuming the child process where it left off and "
5455 "without signal to be sent\n");
5456 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5457
5458 printf("Before calling %s() for the child\n", TWAIT_FNAME);
5459 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5460
5461 validate_status_exited(status, exitval);
5462
5463 printf("Before calling %s() for the child\n", TWAIT_FNAME);
5464 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
5465 }
5466 #endif
5467
5468 volatile lwpid_t the_lwp_id = 0;
5469
5470 static void
lwp_main_func(void * arg)5471 lwp_main_func(void *arg)
5472 {
5473 the_lwp_id = _lwp_self();
5474 _lwp_exit();
5475 }
5476
5477 ATF_TC(lwp_create1);
ATF_TC_HEAD(lwp_create1,tc)5478 ATF_TC_HEAD(lwp_create1, tc)
5479 {
5480 atf_tc_set_md_var(tc, "descr",
5481 "Verify that 1 LWP creation is intercepted by ptrace(2) with "
5482 "EVENT_MASK set to PTRACE_LWP_CREATE");
5483 }
5484
ATF_TC_BODY(lwp_create1,tc)5485 ATF_TC_BODY(lwp_create1, tc)
5486 {
5487 const int exitval = 5;
5488 const int sigval = SIGSTOP;
5489 pid_t child, wpid;
5490 #if defined(TWAIT_HAVE_STATUS)
5491 int status;
5492 #endif
5493 ptrace_state_t state;
5494 const int slen = sizeof(state);
5495 ptrace_event_t event;
5496 const int elen = sizeof(event);
5497 ucontext_t uc;
5498 lwpid_t lid;
5499 static const size_t ssize = 16*1024;
5500 void *stack;
5501
5502 printf("Before forking process PID=%d\n", getpid());
5503 ATF_REQUIRE((child = fork()) != -1);
5504 if (child == 0) {
5505 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
5506 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
5507
5508 printf("Before raising %s from child\n", strsignal(sigval));
5509 FORKEE_ASSERT(raise(sigval) == 0);
5510
5511 printf("Before allocating memory for stack in child\n");
5512 FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
5513
5514 printf("Before making context for new lwp in child\n");
5515 _lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize);
5516
5517 printf("Before creating new in child\n");
5518 FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
5519
5520 printf("Before waiting for lwp %d to exit\n", lid);
5521 FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
5522
5523 printf("Before verifying that reported %d and running lid %d "
5524 "are the same\n", lid, the_lwp_id);
5525 FORKEE_ASSERT_EQ(lid, the_lwp_id);
5526
5527 printf("Before exiting of the child process\n");
5528 _exit(exitval);
5529 }
5530 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
5531
5532 printf("Before calling %s() for the child\n", TWAIT_FNAME);
5533 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5534
5535 validate_status_stopped(status, sigval);
5536
5537 printf("Set empty EVENT_MASK for the child %d\n", child);
5538 event.pe_set_event = PTRACE_LWP_CREATE;
5539 ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
5540
5541 printf("Before resuming the child process where it left off and "
5542 "without signal to be sent\n");
5543 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5544
5545 printf("Before calling %s() for the child - expected stopped "
5546 "SIGTRAP\n", TWAIT_FNAME);
5547 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5548
5549 validate_status_stopped(status, SIGTRAP);
5550
5551 ATF_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
5552
5553 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_CREATE);
5554
5555 lid = state.pe_lwp;
5556 printf("Reported PTRACE_LWP_CREATE event with lid %d\n", lid);
5557
5558 printf("Before resuming the child process where it left off and "
5559 "without signal to be sent\n");
5560 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5561
5562 printf("Before calling %s() for the child - expected exited\n",
5563 TWAIT_FNAME);
5564 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5565
5566 validate_status_exited(status, exitval);
5567
5568 printf("Before calling %s() for the child - expected no process\n",
5569 TWAIT_FNAME);
5570 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
5571 }
5572
5573 ATF_TC(lwp_exit1);
ATF_TC_HEAD(lwp_exit1,tc)5574 ATF_TC_HEAD(lwp_exit1, tc)
5575 {
5576 atf_tc_set_md_var(tc, "descr",
5577 "Verify that 1 LWP creation is intercepted by ptrace(2) with "
5578 "EVENT_MASK set to PTRACE_LWP_EXIT");
5579 }
5580
ATF_TC_BODY(lwp_exit1,tc)5581 ATF_TC_BODY(lwp_exit1, tc)
5582 {
5583 const int exitval = 5;
5584 const int sigval = SIGSTOP;
5585 pid_t child, wpid;
5586 #if defined(TWAIT_HAVE_STATUS)
5587 int status;
5588 #endif
5589 ptrace_state_t state;
5590 const int slen = sizeof(state);
5591 ptrace_event_t event;
5592 const int elen = sizeof(event);
5593 ucontext_t uc;
5594 lwpid_t lid;
5595 static const size_t ssize = 16*1024;
5596 void *stack;
5597
5598 printf("Before forking process PID=%d\n", getpid());
5599 ATF_REQUIRE((child = fork()) != -1);
5600 if (child == 0) {
5601 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
5602 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
5603
5604 printf("Before raising %s from child\n", strsignal(sigval));
5605 FORKEE_ASSERT(raise(sigval) == 0);
5606
5607 printf("Before allocating memory for stack in child\n");
5608 FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
5609
5610 printf("Before making context for new lwp in child\n");
5611 _lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize);
5612
5613 printf("Before creating new in child\n");
5614 FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
5615
5616 printf("Before waiting for lwp %d to exit\n", lid);
5617 FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
5618
5619 printf("Before verifying that reported %d and running lid %d "
5620 "are the same\n", lid, the_lwp_id);
5621 FORKEE_ASSERT_EQ(lid, the_lwp_id);
5622
5623 printf("Before exiting of the child process\n");
5624 _exit(exitval);
5625 }
5626 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
5627
5628 printf("Before calling %s() for the child\n", TWAIT_FNAME);
5629 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5630
5631 validate_status_stopped(status, sigval);
5632
5633 printf("Set empty EVENT_MASK for the child %d\n", child);
5634 event.pe_set_event = PTRACE_LWP_EXIT;
5635 ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
5636
5637 printf("Before resuming the child process where it left off and "
5638 "without signal to be sent\n");
5639 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5640
5641 printf("Before calling %s() for the child - expected stopped "
5642 "SIGTRAP\n", TWAIT_FNAME);
5643 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5644
5645 validate_status_stopped(status, SIGTRAP);
5646
5647 ATF_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
5648
5649 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_EXIT);
5650
5651 lid = state.pe_lwp;
5652 printf("Reported PTRACE_LWP_EXIT event with lid %d\n", lid);
5653
5654 printf("Before resuming the child process where it left off and "
5655 "without signal to be sent\n");
5656 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5657
5658 printf("Before calling %s() for the child - expected exited\n",
5659 TWAIT_FNAME);
5660 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5661
5662 validate_status_exited(status, exitval);
5663
5664 printf("Before calling %s() for the child - expected no process\n",
5665 TWAIT_FNAME);
5666 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
5667 }
5668
5669 ATF_TC(signal1);
ATF_TC_HEAD(signal1,tc)5670 ATF_TC_HEAD(signal1, tc)
5671 {
5672 atf_tc_set_md_var(tc, "descr",
5673 "Verify that masking single unrelated signal does not stop tracer "
5674 "from catching other signals");
5675 }
5676
ATF_TC_BODY(signal1,tc)5677 ATF_TC_BODY(signal1, tc)
5678 {
5679 const int exitval = 5;
5680 const int sigval = SIGSTOP;
5681 const int sigmasked = SIGTRAP;
5682 const int signotmasked = SIGINT;
5683 pid_t child, wpid;
5684 #if defined(TWAIT_HAVE_STATUS)
5685 int status;
5686 #endif
5687 sigset_t intmask;
5688
5689 printf("Before forking process PID=%d\n", getpid());
5690 ATF_REQUIRE((child = fork()) != -1);
5691 if (child == 0) {
5692 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
5693 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
5694
5695 sigemptyset(&intmask);
5696 sigaddset(&intmask, sigmasked);
5697 sigprocmask(SIG_BLOCK, &intmask, NULL);
5698
5699 printf("Before raising %s from child\n", strsignal(sigval));
5700 FORKEE_ASSERT(raise(sigval) == 0);
5701
5702 printf("Before raising %s from child\n",
5703 strsignal(signotmasked));
5704 FORKEE_ASSERT(raise(signotmasked) == 0);
5705
5706 printf("Before exiting of the child process\n");
5707 _exit(exitval);
5708 }
5709 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
5710
5711 printf("Before calling %s() for the child\n", TWAIT_FNAME);
5712 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5713
5714 validate_status_stopped(status, sigval);
5715
5716 printf("Before resuming the child process where it left off and "
5717 "without signal to be sent\n");
5718 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5719
5720 printf("Before calling %s() for the child\n", TWAIT_FNAME);
5721 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5722
5723 validate_status_stopped(status, signotmasked);
5724
5725 printf("Before resuming the child process where it left off and "
5726 "without signal to be sent\n");
5727 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5728
5729 printf("Before calling %s() for the child\n", TWAIT_FNAME);
5730 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5731
5732 validate_status_exited(status, exitval);
5733
5734 printf("Before calling %s() for the child\n", TWAIT_FNAME);
5735 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
5736 }
5737
5738 ATF_TC(signal2);
ATF_TC_HEAD(signal2,tc)5739 ATF_TC_HEAD(signal2, tc)
5740 {
5741 atf_tc_set_md_var(tc, "descr",
5742 "Verify that masking SIGTRAP in tracee stops tracer from "
5743 "catching this raised signal");
5744 }
5745
ATF_TC_BODY(signal2,tc)5746 ATF_TC_BODY(signal2, tc)
5747 {
5748 const int exitval = 5;
5749 const int sigval = SIGSTOP;
5750 const int sigmasked = SIGTRAP;
5751 pid_t child, wpid;
5752 #if defined(TWAIT_HAVE_STATUS)
5753 int status;
5754 #endif
5755 sigset_t intmask;
5756
5757 printf("Before forking process PID=%d\n", getpid());
5758 ATF_REQUIRE((child = fork()) != -1);
5759 if (child == 0) {
5760 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
5761 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
5762
5763 sigemptyset(&intmask);
5764 sigaddset(&intmask, sigmasked);
5765 sigprocmask(SIG_BLOCK, &intmask, NULL);
5766
5767 printf("Before raising %s from child\n", strsignal(sigval));
5768 FORKEE_ASSERT(raise(sigval) == 0);
5769
5770 printf("Before raising %s breakpoint from child\n",
5771 strsignal(sigmasked));
5772 FORKEE_ASSERT(raise(sigmasked) == 0);
5773
5774 printf("Before exiting of the child process\n");
5775 _exit(exitval);
5776 }
5777 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
5778
5779 printf("Before calling %s() for the child\n", TWAIT_FNAME);
5780 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5781
5782 validate_status_stopped(status, sigval);
5783
5784 printf("Before resuming the child process where it left off and "
5785 "without signal to be sent\n");
5786 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5787
5788 printf("Before calling %s() for the child\n", TWAIT_FNAME);
5789 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5790
5791 validate_status_exited(status, exitval);
5792
5793 printf("Before calling %s() for the child\n", TWAIT_FNAME);
5794 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
5795 }
5796
5797 ATF_TC(signal3);
ATF_TC_HEAD(signal3,tc)5798 ATF_TC_HEAD(signal3, tc)
5799 {
5800 atf_tc_set_md_var(tc, "descr",
5801 "Verify that masking SIGTRAP in tracee does not stop tracer from "
5802 "catching software breakpoints");
5803 }
5804
ATF_TC_BODY(signal3,tc)5805 ATF_TC_BODY(signal3, tc)
5806 {
5807 const int exitval = 5;
5808 const int sigval = SIGSTOP;
5809 const int sigmasked = SIGTRAP;
5810 pid_t child, wpid;
5811 #if defined(TWAIT_HAVE_STATUS)
5812 int status;
5813 #endif
5814 sigset_t intmask;
5815
5816 atf_tc_expect_fail("PR kern/51918");
5817
5818 printf("Before forking process PID=%d\n", getpid());
5819 ATF_REQUIRE((child = fork()) != -1);
5820 if (child == 0) {
5821 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
5822 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
5823
5824 sigemptyset(&intmask);
5825 sigaddset(&intmask, sigmasked);
5826 sigprocmask(SIG_BLOCK, &intmask, NULL);
5827
5828 printf("Before raising %s from child\n", strsignal(sigval));
5829 FORKEE_ASSERT(raise(sigval) == 0);
5830
5831 printf("Before raising software breakpoint from child\n");
5832 #if defined(__x86_64__)
5833 __asm__ __volatile__ ("int3\n;");
5834 #else
5835 /* port me */
5836 #endif
5837
5838 printf("Before exiting of the child process\n");
5839 _exit(exitval);
5840 }
5841 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
5842
5843 printf("Before calling %s() for the child\n", TWAIT_FNAME);
5844 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5845
5846 validate_status_stopped(status, sigval);
5847
5848 printf("Before resuming the child process where it left off and "
5849 "without signal to be sent\n");
5850 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5851
5852 printf("Before calling %s() for the child\n", TWAIT_FNAME);
5853 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5854
5855 validate_status_stopped(status, sigmasked);
5856
5857 printf("Before resuming the child process where it left off and "
5858 "without signal to be sent\n");
5859 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5860
5861 printf("Before calling %s() for the child\n", TWAIT_FNAME);
5862 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5863
5864 validate_status_exited(status, exitval);
5865
5866 printf("Before calling %s() for the child\n", TWAIT_FNAME);
5867 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
5868 }
5869
5870 #if defined(PT_STEP)
5871 ATF_TC(signal4);
ATF_TC_HEAD(signal4,tc)5872 ATF_TC_HEAD(signal4, tc)
5873 {
5874 atf_tc_set_md_var(tc, "descr",
5875 "Verify that masking SIGTRAP in tracee does not stop tracer from "
5876 "catching single step trap");
5877 }
5878
ATF_TC_BODY(signal4,tc)5879 ATF_TC_BODY(signal4, tc)
5880 {
5881 const int exitval = 5;
5882 const int sigval = SIGSTOP;
5883 const int sigmasked = SIGTRAP;
5884 pid_t child, wpid;
5885 #if defined(TWAIT_HAVE_STATUS)
5886 int status;
5887 #endif
5888 sigset_t intmask;
5889 int happy;
5890
5891 atf_tc_expect_fail("PR kern/51918");
5892
5893 printf("Before forking process PID=%d\n", getpid());
5894 ATF_REQUIRE((child = fork()) != -1);
5895 if (child == 0) {
5896 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
5897 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
5898
5899 happy = check_happy(100);
5900
5901 sigemptyset(&intmask);
5902 sigaddset(&intmask, sigmasked);
5903 sigprocmask(SIG_BLOCK, &intmask, NULL);
5904
5905 printf("Before raising %s from child\n", strsignal(sigval));
5906 FORKEE_ASSERT(raise(sigval) == 0);
5907
5908 FORKEE_ASSERT_EQ(happy, check_happy(100));
5909
5910 printf("Before exiting of the child process\n");
5911 _exit(exitval);
5912 }
5913 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
5914
5915 printf("Before calling %s() for the child\n", TWAIT_FNAME);
5916 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5917
5918 validate_status_stopped(status, sigval);
5919
5920 printf("Before resuming the child process where it left off and "
5921 "without signal to be sent\n");
5922 ATF_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0) != -1);
5923
5924 printf("Before calling %s() for the child\n", TWAIT_FNAME);
5925 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5926
5927 validate_status_stopped(status, sigmasked);
5928
5929 printf("Before resuming the child process where it left off and "
5930 "without signal to be sent\n");
5931 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5932
5933 printf("Before calling %s() for the child\n", TWAIT_FNAME);
5934 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5935
5936 validate_status_exited(status, exitval);
5937
5938 printf("Before calling %s() for the child\n", TWAIT_FNAME);
5939 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
5940 }
5941 #endif
5942
5943 ATF_TC(signal5);
ATF_TC_HEAD(signal5,tc)5944 ATF_TC_HEAD(signal5, tc)
5945 {
5946 atf_tc_set_md_var(tc, "descr",
5947 "Verify that masking SIGTRAP in tracee does not stop tracer from "
5948 "catching exec() breakpoint");
5949 }
5950
ATF_TC_BODY(signal5,tc)5951 ATF_TC_BODY(signal5, tc)
5952 {
5953 const int exitval = 5;
5954 const int sigval = SIGSTOP;
5955 const int sigmasked = SIGTRAP;
5956 pid_t child, wpid;
5957 #if defined(TWAIT_HAVE_STATUS)
5958 int status;
5959 #endif
5960 sigset_t intmask;
5961
5962 atf_tc_expect_fail("PR kern/51918");
5963
5964 printf("Before forking process PID=%d\n", getpid());
5965 ATF_REQUIRE((child = fork()) != -1);
5966 if (child == 0) {
5967 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
5968 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
5969
5970 sigemptyset(&intmask);
5971 sigaddset(&intmask, sigmasked);
5972 sigprocmask(SIG_BLOCK, &intmask, NULL);
5973
5974 printf("Before raising %s from child\n", strsignal(sigval));
5975 FORKEE_ASSERT(raise(sigval) == 0);
5976
5977 printf("Before calling execve(2) from child\n");
5978 execlp("/bin/echo", "/bin/echo", NULL);
5979
5980 printf("Before exiting of the child process\n");
5981 _exit(exitval);
5982 }
5983 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
5984
5985 printf("Before calling %s() for the child\n", TWAIT_FNAME);
5986 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5987
5988 validate_status_stopped(status, sigval);
5989
5990 printf("Before resuming the child process where it left off and "
5991 "without signal to be sent\n");
5992 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5993
5994 printf("Before calling %s() for the child\n", TWAIT_FNAME);
5995 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5996
5997 validate_status_stopped(status, sigmasked);
5998
5999 printf("Before resuming the child process where it left off and "
6000 "without signal to be sent\n");
6001 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6002
6003 printf("Before calling %s() for the child\n", TWAIT_FNAME);
6004 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6005
6006 validate_status_exited(status, exitval);
6007
6008 printf("Before calling %s() for the child\n", TWAIT_FNAME);
6009 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
6010 }
6011
6012 #if defined(TWAIT_HAVE_PID)
6013 ATF_TC(signal6);
ATF_TC_HEAD(signal6,tc)6014 ATF_TC_HEAD(signal6, tc)
6015 {
6016 atf_tc_set_md_var(tc, "descr",
6017 "Verify that masking SIGTRAP in tracee does not stop tracer from "
6018 "catching PTRACE_FORK breakpoint");
6019 }
6020
ATF_TC_BODY(signal6,tc)6021 ATF_TC_BODY(signal6, tc)
6022 {
6023 const int exitval = 5;
6024 const int exitval2 = 15;
6025 const int sigval = SIGSTOP;
6026 const int sigmasked = SIGTRAP;
6027 pid_t child, child2, wpid;
6028 #if defined(TWAIT_HAVE_STATUS)
6029 int status;
6030 #endif
6031 sigset_t intmask;
6032 ptrace_state_t state;
6033 const int slen = sizeof(state);
6034 ptrace_event_t event;
6035 const int elen = sizeof(event);
6036
6037 atf_tc_expect_fail("PR kern/51918");
6038
6039 printf("Before forking process PID=%d\n", getpid());
6040 ATF_REQUIRE((child = fork()) != -1);
6041 if (child == 0) {
6042 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
6043 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
6044
6045 sigemptyset(&intmask);
6046 sigaddset(&intmask, sigmasked);
6047 sigprocmask(SIG_BLOCK, &intmask, NULL);
6048
6049 printf("Before raising %s from child\n", strsignal(sigval));
6050 FORKEE_ASSERT(raise(sigval) == 0);
6051
6052 FORKEE_ASSERT((child2 = fork()) != 1);
6053
6054 if (child2 == 0)
6055 _exit(exitval2);
6056
6057 FORKEE_REQUIRE_SUCCESS
6058 (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
6059
6060 forkee_status_exited(status, exitval2);
6061
6062 printf("Before exiting of the child process\n");
6063 _exit(exitval);
6064 }
6065 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
6066
6067 printf("Before calling %s() for the child\n", TWAIT_FNAME);
6068 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6069
6070 validate_status_stopped(status, sigval);
6071
6072 printf("Enable PTRACE_FORK in EVENT_MASK for the child %d\n", child);
6073 event.pe_set_event = PTRACE_FORK;
6074 ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
6075
6076 printf("Before resuming the child process where it left off and "
6077 "without signal to be sent\n");
6078 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6079
6080 printf("Before calling %s() for the child\n", TWAIT_FNAME);
6081 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6082
6083 validate_status_stopped(status, sigmasked);
6084
6085 ATF_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
6086 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
6087
6088 child2 = state.pe_other_pid;
6089 printf("Reported PTRACE_FORK event with forkee %d\n", child2);
6090
6091 printf("Before calling %s() for the child2\n", TWAIT_FNAME);
6092 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
6093 child2);
6094
6095 validate_status_stopped(status, SIGTRAP);
6096
6097 ATF_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
6098 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
6099 ATF_REQUIRE_EQ(state.pe_other_pid, child);
6100
6101 printf("Before resuming the forkee process where it left off and "
6102 "without signal to be sent\n");
6103 ATF_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
6104
6105 printf("Before resuming the child process where it left off and "
6106 "without signal to be sent\n");
6107 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6108
6109 printf("Before calling %s() for the forkee - expected exited\n",
6110 TWAIT_FNAME);
6111 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
6112 child2);
6113
6114 validate_status_exited(status, exitval2);
6115
6116 printf("Before calling %s() for the forkee - expected no process\n",
6117 TWAIT_FNAME);
6118 TWAIT_REQUIRE_FAILURE(ECHILD,
6119 wpid = TWAIT_GENERIC(child2, &status, 0));
6120
6121 printf("Before calling %s() for the child - expected stopped "
6122 "SIGCHLD\n", TWAIT_FNAME);
6123 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6124
6125 validate_status_stopped(status, SIGCHLD);
6126
6127 printf("Before resuming the child process where it left off and "
6128 "without signal to be sent\n");
6129 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6130
6131 printf("Before calling %s() for the child - expected exited\n",
6132 TWAIT_FNAME);
6133 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6134
6135 validate_status_exited(status, exitval);
6136
6137 printf("Before calling %s() for the child - expected no process\n",
6138 TWAIT_FNAME);
6139 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
6140 }
6141 #endif
6142
6143 #if defined(TWAIT_HAVE_PID)
6144 ATF_TC(signal7);
ATF_TC_HEAD(signal7,tc)6145 ATF_TC_HEAD(signal7, tc)
6146 {
6147 atf_tc_set_md_var(tc, "descr",
6148 "Verify that masking SIGTRAP in tracee does not stop tracer from "
6149 "catching PTRACE_VFORK breakpoint");
6150 }
6151
ATF_TC_BODY(signal7,tc)6152 ATF_TC_BODY(signal7, tc)
6153 {
6154 const int exitval = 5;
6155 const int exitval2 = 15;
6156 const int sigval = SIGSTOP;
6157 const int sigmasked = SIGTRAP;
6158 pid_t child, child2, wpid;
6159 #if defined(TWAIT_HAVE_STATUS)
6160 int status;
6161 #endif
6162 sigset_t intmask;
6163 ptrace_state_t state;
6164 const int slen = sizeof(state);
6165 ptrace_event_t event;
6166 const int elen = sizeof(event);
6167
6168 atf_tc_expect_fail("PR kern/51918 PR kern/51630");
6169
6170 printf("Before forking process PID=%d\n", getpid());
6171 ATF_REQUIRE((child = fork()) != -1);
6172 if (child == 0) {
6173 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
6174 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
6175
6176 sigemptyset(&intmask);
6177 sigaddset(&intmask, sigmasked);
6178 sigprocmask(SIG_BLOCK, &intmask, NULL);
6179
6180 printf("Before raising %s from child\n", strsignal(sigval));
6181 FORKEE_ASSERT(raise(sigval) == 0);
6182
6183 FORKEE_ASSERT((child2 = fork()) != 1);
6184
6185 if (child2 == 0)
6186 _exit(exitval2);
6187
6188 FORKEE_REQUIRE_SUCCESS
6189 (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
6190
6191 forkee_status_exited(status, exitval2);
6192
6193 printf("Before exiting of the child process\n");
6194 _exit(exitval);
6195 }
6196 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
6197
6198 printf("Before calling %s() for the child\n", TWAIT_FNAME);
6199 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6200
6201 validate_status_stopped(status, sigval);
6202
6203 printf("Enable PTRACE_VFORK in EVENT_MASK for the child %d\n", child);
6204 event.pe_set_event = PTRACE_VFORK;
6205 ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
6206
6207 printf("Before resuming the child process where it left off and "
6208 "without signal to be sent\n");
6209 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6210
6211 printf("Before calling %s() for the child\n", TWAIT_FNAME);
6212 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6213
6214 validate_status_stopped(status, sigmasked);
6215
6216 ATF_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
6217 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK);
6218
6219 child2 = state.pe_other_pid;
6220 printf("Reported PTRACE_VFORK event with forkee %d\n", child2);
6221
6222 printf("Before calling %s() for the child2\n", TWAIT_FNAME);
6223 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
6224 child2);
6225
6226 validate_status_stopped(status, SIGTRAP);
6227
6228 ATF_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
6229 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK);
6230 ATF_REQUIRE_EQ(state.pe_other_pid, child);
6231
6232 printf("Before resuming the forkee process where it left off and "
6233 "without signal to be sent\n");
6234 ATF_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
6235
6236 printf("Before resuming the child process where it left off and "
6237 "without signal to be sent\n");
6238 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6239
6240 printf("Before calling %s() for the forkee - expected exited\n",
6241 TWAIT_FNAME);
6242 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
6243 child2);
6244
6245 validate_status_exited(status, exitval2);
6246
6247 printf("Before calling %s() for the forkee - expected no process\n",
6248 TWAIT_FNAME);
6249 TWAIT_REQUIRE_FAILURE(ECHILD,
6250 wpid = TWAIT_GENERIC(child2, &status, 0));
6251
6252 printf("Before calling %s() for the child - expected stopped "
6253 "SIGCHLD\n", TWAIT_FNAME);
6254 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6255
6256 validate_status_stopped(status, SIGCHLD);
6257
6258 printf("Before resuming the child process where it left off and "
6259 "without signal to be sent\n");
6260 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6261
6262 printf("Before calling %s() for the child - expected exited\n",
6263 TWAIT_FNAME);
6264 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6265
6266 validate_status_exited(status, exitval);
6267
6268 printf("Before calling %s() for the child - expected no process\n",
6269 TWAIT_FNAME);
6270 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
6271 }
6272 #endif
6273
6274 ATF_TC(signal8);
ATF_TC_HEAD(signal8,tc)6275 ATF_TC_HEAD(signal8, tc)
6276 {
6277 atf_tc_set_md_var(tc, "descr",
6278 "Verify that masking SIGTRAP in tracee does not stop tracer from "
6279 "catching PTRACE_VFORK_DONE breakpoint");
6280 }
6281
ATF_TC_BODY(signal8,tc)6282 ATF_TC_BODY(signal8, tc)
6283 {
6284 const int exitval = 5;
6285 const int exitval2 = 15;
6286 const int sigval = SIGSTOP;
6287 const int sigmasked = SIGTRAP;
6288 pid_t child, child2, wpid;
6289 #if defined(TWAIT_HAVE_STATUS)
6290 int status;
6291 #endif
6292 sigset_t intmask;
6293 ptrace_state_t state;
6294 const int slen = sizeof(state);
6295 ptrace_event_t event;
6296 const int elen = sizeof(event);
6297
6298 atf_tc_expect_fail("PR kern/51918");
6299
6300 printf("Before forking process PID=%d\n", getpid());
6301 ATF_REQUIRE((child = fork()) != -1);
6302 if (child == 0) {
6303 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
6304 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
6305
6306 sigemptyset(&intmask);
6307 sigaddset(&intmask, sigmasked);
6308 sigprocmask(SIG_BLOCK, &intmask, NULL);
6309
6310 printf("Before raising %s from child\n", strsignal(sigval));
6311 FORKEE_ASSERT(raise(sigval) == 0);
6312
6313 FORKEE_ASSERT((child2 = vfork()) != 1);
6314
6315 if (child2 == 0)
6316 _exit(exitval2);
6317
6318 FORKEE_REQUIRE_SUCCESS
6319 (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
6320
6321 forkee_status_exited(status, exitval2);
6322
6323 printf("Before exiting of the child process\n");
6324 _exit(exitval);
6325 }
6326 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
6327
6328 printf("Before calling %s() for the child\n", TWAIT_FNAME);
6329 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6330
6331 validate_status_stopped(status, sigval);
6332
6333 printf("Enable PTRACE_VFORK_DONE in EVENT_MASK for the child %d\n",
6334 child);
6335 event.pe_set_event = PTRACE_VFORK_DONE;
6336 ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
6337
6338 printf("Before resuming the child process where it left off and "
6339 "without signal to be sent\n");
6340 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6341
6342 printf("Before calling %s() for the child\n", TWAIT_FNAME);
6343 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6344
6345 validate_status_stopped(status, sigmasked);
6346
6347 ATF_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
6348 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE);
6349
6350 child2 = state.pe_other_pid;
6351 printf("Reported PTRACE_VFORK_DONE event with forkee %d\n", child2);
6352
6353 printf("Before resuming the child process where it left off and "
6354 "without signal to be sent\n");
6355 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6356
6357 printf("Before calling %s() for the child - expected stopped "
6358 "SIGCHLD\n", TWAIT_FNAME);
6359 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6360
6361 validate_status_stopped(status, SIGCHLD);
6362
6363 printf("Before resuming the child process where it left off and "
6364 "without signal to be sent\n");
6365 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6366
6367 printf("Before calling %s() for the child - expected exited\n",
6368 TWAIT_FNAME);
6369 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6370
6371 validate_status_exited(status, exitval);
6372
6373 printf("Before calling %s() for the child - expected no process\n",
6374 TWAIT_FNAME);
6375 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
6376 }
6377
6378 ATF_TC(signal9);
ATF_TC_HEAD(signal9,tc)6379 ATF_TC_HEAD(signal9, tc)
6380 {
6381 atf_tc_set_md_var(tc, "descr",
6382 "Verify that masking SIGTRAP in tracee does not stop tracer from "
6383 "catching PTRACE_LWP_CREATE breakpoint");
6384 }
6385
ATF_TC_BODY(signal9,tc)6386 ATF_TC_BODY(signal9, tc)
6387 {
6388 const int exitval = 5;
6389 const int sigval = SIGSTOP;
6390 const int sigmasked = SIGTRAP;
6391 pid_t child, wpid;
6392 #if defined(TWAIT_HAVE_STATUS)
6393 int status;
6394 #endif
6395 sigset_t intmask;
6396 ptrace_state_t state;
6397 const int slen = sizeof(state);
6398 ptrace_event_t event;
6399 const int elen = sizeof(event);
6400 ucontext_t uc;
6401 lwpid_t lid;
6402 static const size_t ssize = 16*1024;
6403 void *stack;
6404
6405 atf_tc_expect_fail("PR kern/51918");
6406
6407 printf("Before forking process PID=%d\n", getpid());
6408 ATF_REQUIRE((child = fork()) != -1);
6409 if (child == 0) {
6410 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
6411 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
6412
6413 sigemptyset(&intmask);
6414 sigaddset(&intmask, sigmasked);
6415 sigprocmask(SIG_BLOCK, &intmask, NULL);
6416
6417 printf("Before raising %s from child\n", strsignal(sigval));
6418 FORKEE_ASSERT(raise(sigval) == 0);
6419
6420 printf("Before allocating memory for stack in child\n");
6421 FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
6422
6423 printf("Before making context for new lwp in child\n");
6424 _lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize);
6425
6426 printf("Before creating new in child\n");
6427 FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
6428
6429 printf("Before waiting for lwp %d to exit\n", lid);
6430 FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
6431
6432 printf("Before verifying that reported %d and running lid %d "
6433 "are the same\n", lid, the_lwp_id);
6434 FORKEE_ASSERT_EQ(lid, the_lwp_id);
6435
6436 printf("Before exiting of the child process\n");
6437 _exit(exitval);
6438 }
6439 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
6440
6441 printf("Before calling %s() for the child\n", TWAIT_FNAME);
6442 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6443
6444 validate_status_stopped(status, sigval);
6445
6446 printf("Set empty EVENT_MASK for the child %d\n", child);
6447 event.pe_set_event = PTRACE_LWP_CREATE;
6448 ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
6449
6450 printf("Before resuming the child process where it left off and "
6451 "without signal to be sent\n");
6452 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6453
6454 printf("Before calling %s() for the child - expected stopped "
6455 "SIGTRAP\n", TWAIT_FNAME);
6456 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6457
6458 validate_status_stopped(status, sigmasked);
6459
6460 ATF_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
6461
6462 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_CREATE);
6463
6464 lid = state.pe_lwp;
6465 printf("Reported PTRACE_LWP_CREATE event with lid %d\n", lid);
6466
6467 printf("Before resuming the child process where it left off and "
6468 "without signal to be sent\n");
6469 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6470
6471 printf("Before calling %s() for the child - expected exited\n",
6472 TWAIT_FNAME);
6473 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6474
6475 validate_status_exited(status, exitval);
6476
6477 printf("Before calling %s() for the child - expected no process\n",
6478 TWAIT_FNAME);
6479 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
6480 }
6481
6482 ATF_TC(signal10);
ATF_TC_HEAD(signal10,tc)6483 ATF_TC_HEAD(signal10, tc)
6484 {
6485 atf_tc_set_md_var(tc, "descr",
6486 "Verify that masking SIGTRAP in tracee does not stop tracer from "
6487 "catching PTRACE_LWP_EXIT breakpoint");
6488 }
6489
ATF_TC_BODY(signal10,tc)6490 ATF_TC_BODY(signal10, tc)
6491 {
6492 const int exitval = 5;
6493 const int sigval = SIGSTOP;
6494 const int sigmasked = SIGTRAP;
6495 pid_t child, wpid;
6496 #if defined(TWAIT_HAVE_STATUS)
6497 int status;
6498 #endif
6499 sigset_t intmask;
6500 ptrace_state_t state;
6501 const int slen = sizeof(state);
6502 ptrace_event_t event;
6503 const int elen = sizeof(event);
6504 ucontext_t uc;
6505 lwpid_t lid;
6506 static const size_t ssize = 16*1024;
6507 void *stack;
6508
6509 atf_tc_expect_fail("PR kern/51918");
6510
6511 printf("Before forking process PID=%d\n", getpid());
6512 ATF_REQUIRE((child = fork()) != -1);
6513 if (child == 0) {
6514 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
6515 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
6516
6517 sigemptyset(&intmask);
6518 sigaddset(&intmask, sigmasked);
6519 sigprocmask(SIG_BLOCK, &intmask, NULL);
6520
6521 printf("Before raising %s from child\n", strsignal(sigval));
6522 FORKEE_ASSERT(raise(sigval) == 0);
6523
6524 printf("Before allocating memory for stack in child\n");
6525 FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
6526
6527 printf("Before making context for new lwp in child\n");
6528 _lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize);
6529
6530 printf("Before creating new in child\n");
6531 FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
6532
6533 printf("Before waiting for lwp %d to exit\n", lid);
6534 FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
6535
6536 printf("Before verifying that reported %d and running lid %d "
6537 "are the same\n", lid, the_lwp_id);
6538 FORKEE_ASSERT_EQ(lid, the_lwp_id);
6539
6540 printf("Before exiting of the child process\n");
6541 _exit(exitval);
6542 }
6543 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
6544
6545 printf("Before calling %s() for the child\n", TWAIT_FNAME);
6546 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6547
6548 validate_status_stopped(status, sigval);
6549
6550 printf("Set empty EVENT_MASK for the child %d\n", child);
6551 event.pe_set_event = PTRACE_LWP_EXIT;
6552 ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
6553
6554 printf("Before resuming the child process where it left off and "
6555 "without signal to be sent\n");
6556 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6557
6558 printf("Before calling %s() for the child - expected stopped "
6559 "SIGTRAP\n", TWAIT_FNAME);
6560 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6561
6562 validate_status_stopped(status, sigmasked);
6563
6564 ATF_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
6565
6566 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_EXIT);
6567
6568 lid = state.pe_lwp;
6569 printf("Reported PTRACE_LWP_EXIT event with lid %d\n", lid);
6570
6571 printf("Before resuming the child process where it left off and "
6572 "without signal to be sent\n");
6573 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6574
6575 printf("Before calling %s() for the child - expected exited\n",
6576 TWAIT_FNAME);
6577 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6578
6579 validate_status_exited(status, exitval);
6580
6581 printf("Before calling %s() for the child - expected no process\n",
6582 TWAIT_FNAME);
6583 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
6584 }
6585
ATF_TP_ADD_TCS(tp)6586 ATF_TP_ADD_TCS(tp)
6587 {
6588 setvbuf(stdout, NULL, _IONBF, 0);
6589 setvbuf(stderr, NULL, _IONBF, 0);
6590 ATF_TP_ADD_TC(tp, traceme1);
6591 ATF_TP_ADD_TC(tp, traceme2);
6592 ATF_TP_ADD_TC(tp, traceme3);
6593 ATF_TP_ADD_TC(tp, traceme4);
6594
6595 ATF_TP_ADD_TC_HAVE_PID(tp, attach1);
6596 ATF_TP_ADD_TC_HAVE_PID(tp, attach2);
6597 ATF_TP_ADD_TC(tp, attach3);
6598 ATF_TP_ADD_TC(tp, attach4);
6599 ATF_TP_ADD_TC_HAVE_PID(tp, attach5);
6600 ATF_TP_ADD_TC_HAVE_PID(tp, attach6);
6601 ATF_TP_ADD_TC_HAVE_PID(tp, attach7);
6602
6603 ATF_TP_ADD_TC(tp, eventmask1);
6604 ATF_TP_ADD_TC(tp, eventmask2);
6605 ATF_TP_ADD_TC(tp, eventmask3);
6606 ATF_TP_ADD_TC(tp, eventmask4);
6607 ATF_TP_ADD_TC(tp, eventmask5);
6608 ATF_TP_ADD_TC(tp, eventmask6);
6609
6610 ATF_TP_ADD_TC_HAVE_PID(tp, fork1);
6611 ATF_TP_ADD_TC(tp, fork2);
6612
6613 ATF_TP_ADD_TC_HAVE_PID(tp, vfork1);
6614 ATF_TP_ADD_TC(tp, vfork2);
6615
6616 ATF_TP_ADD_TC(tp, vforkdone1);
6617 ATF_TP_ADD_TC(tp, vforkdone2);
6618
6619 ATF_TP_ADD_TC(tp, io_read_d1);
6620 ATF_TP_ADD_TC(tp, io_read_d2);
6621 ATF_TP_ADD_TC(tp, io_read_d3);
6622 ATF_TP_ADD_TC(tp, io_read_d4);
6623
6624 ATF_TP_ADD_TC(tp, io_write_d1);
6625 ATF_TP_ADD_TC(tp, io_write_d2);
6626 ATF_TP_ADD_TC(tp, io_write_d3);
6627 ATF_TP_ADD_TC(tp, io_write_d4);
6628
6629 ATF_TP_ADD_TC(tp, read_d1);
6630 ATF_TP_ADD_TC(tp, read_d2);
6631 ATF_TP_ADD_TC(tp, read_d3);
6632 ATF_TP_ADD_TC(tp, read_d4);
6633
6634 ATF_TP_ADD_TC(tp, write_d1);
6635 ATF_TP_ADD_TC(tp, write_d2);
6636 ATF_TP_ADD_TC(tp, write_d3);
6637 ATF_TP_ADD_TC(tp, write_d4);
6638
6639 ATF_TP_ADD_TC(tp, io_read_d_write_d_handshake1);
6640 ATF_TP_ADD_TC(tp, io_read_d_write_d_handshake2);
6641
6642 ATF_TP_ADD_TC(tp, read_d_write_d_handshake1);
6643 ATF_TP_ADD_TC(tp, read_d_write_d_handshake2);
6644
6645 ATF_TP_ADD_TC(tp, io_read_i1);
6646 ATF_TP_ADD_TC(tp, io_read_i2);
6647 ATF_TP_ADD_TC(tp, io_read_i3);
6648 ATF_TP_ADD_TC(tp, io_read_i4);
6649
6650 ATF_TP_ADD_TC(tp, read_i1);
6651 ATF_TP_ADD_TC(tp, read_i2);
6652 ATF_TP_ADD_TC(tp, read_i3);
6653 ATF_TP_ADD_TC(tp, read_i4);
6654
6655 ATF_TP_ADD_TC(tp, io_read_auxv1);
6656
6657 ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs1);
6658 ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs2);
6659 ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs3);
6660 ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs4);
6661 ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs5);
6662
6663 ATF_TP_ADD_TC_HAVE_FPREGS(tp, fpregs1);
6664 ATF_TP_ADD_TC_HAVE_FPREGS(tp, fpregs2);
6665
6666 ATF_TP_ADD_TC_PT_STEP(tp, step1);
6667 ATF_TP_ADD_TC_PT_STEP(tp, step2);
6668 ATF_TP_ADD_TC_PT_STEP(tp, step3);
6669 ATF_TP_ADD_TC_PT_STEP(tp, step4);
6670
6671 ATF_TP_ADD_TC(tp, kill1);
6672 ATF_TP_ADD_TC(tp, kill2);
6673
6674 ATF_TP_ADD_TC(tp, lwpinfo1);
6675 ATF_TP_ADD_TC_HAVE_PID(tp, lwpinfo2);
6676
6677 ATF_TP_ADD_TC(tp, siginfo1);
6678 ATF_TP_ADD_TC(tp, siginfo2);
6679 ATF_TP_ADD_TC(tp, siginfo3);
6680 ATF_TP_ADD_TC(tp, siginfo4);
6681 ATF_TP_ADD_TC_HAVE_PID(tp, siginfo5);
6682 ATF_TP_ADD_TC_PT_STEP(tp, siginfo6);
6683
6684 ATF_TP_ADD_TC(tp, lwp_create1);
6685
6686 ATF_TP_ADD_TC(tp, lwp_exit1);
6687
6688 ATF_TP_ADD_TC(tp, signal1);
6689 ATF_TP_ADD_TC(tp, signal2);
6690 ATF_TP_ADD_TC(tp, signal3);
6691 ATF_TP_ADD_TC_PT_STEP(tp, signal4);
6692 ATF_TP_ADD_TC(tp, signal5);
6693 ATF_TP_ADD_TC_HAVE_PID(tp, signal6);
6694 ATF_TP_ADD_TC_HAVE_PID(tp, signal7);
6695 ATF_TP_ADD_TC(tp, signal8);
6696 ATF_TP_ADD_TC(tp, signal9);
6697 ATF_TP_ADD_TC(tp, signal10);
6698
6699 return atf_no_error();
6700 }
6701