1 /*-
2 * SPDX-License-Identifier: BSD-4-Clause
3 *
4 * Copyright 1997 Sean Eric Fagan
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. All advertising materials mentioning features or use of this software
15 * must display the following acknowledgement:
16 * This product includes software developed by Sean Eric Fagan
17 * 4. Neither the name of the author may be used to endorse or promote
18 * products derived from this software without specific prior written
19 * permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34 /*
35 * Various setup functions for truss. Not the cleanest-written code,
36 * I'm afraid.
37 */
38
39 #include <sys/capsicum.h>
40 #include <sys/event.h>
41 #include <sys/ptrace.h>
42 #include <sys/procdesc.h>
43 #include <sys/syscall.h>
44 #include <sys/sysctl.h>
45 #include <sys/time.h>
46 #include <sys/wait.h>
47
48 #include <assert.h>
49 #include <capsicum_helpers.h>
50 #include <err.h>
51 #include <errno.h>
52 #include <signal.h>
53 #include <stdbool.h>
54 #include <stdint.h>
55 #include <stdio.h>
56 #include <stdlib.h>
57 #include <string.h>
58 #include <sysdecode.h>
59 #include <time.h>
60 #include <unistd.h>
61
62 #include "truss.h"
63 #include "syscall.h"
64 #include "extern.h"
65
66 #define WFLAGS (WTRAPPED | WEXITED | WCONTINUED | WUNTRACED)
67
68 struct procabi_table {
69 const char *name;
70 struct procabi *abi;
71 };
72
73 static sig_atomic_t detaching;
74
75 static void enter_syscall(struct trussinfo *, struct threadinfo *,
76 struct ptrace_lwpinfo *);
77 static bool new_proc(struct trussinfo *, pid_t, lwpid_t, int, bool, bool);
78 static void new_proc_register_kev(struct trussinfo *info, int pfd);
79 static struct procinfo *find_proc(struct trussinfo *info, pid_t pid);
80
81 static struct procabi freebsd = {
82 .type = "FreeBSD",
83 .abi = SYSDECODE_ABI_FREEBSD,
84 .pointer_size = sizeof(void *),
85 .extra_syscalls = STAILQ_HEAD_INITIALIZER(freebsd.extra_syscalls),
86 .syscalls = { NULL }
87 };
88
89 #if !defined(__SIZEOF_POINTER__)
90 #error "Use a modern compiler."
91 #endif
92
93 #if __SIZEOF_POINTER__ > 4
94 static struct procabi freebsd32 = {
95 .type = "FreeBSD32",
96 .abi = SYSDECODE_ABI_FREEBSD32,
97 .pointer_size = sizeof(uint32_t),
98 .compat_prefix = "freebsd32_",
99 .extra_syscalls = STAILQ_HEAD_INITIALIZER(freebsd32.extra_syscalls),
100 .syscalls = { NULL }
101 };
102 #endif
103
104 static struct procabi linux = {
105 .type = "Linux",
106 .abi = SYSDECODE_ABI_LINUX,
107 .pointer_size = sizeof(void *),
108 .extra_syscalls = STAILQ_HEAD_INITIALIZER(linux.extra_syscalls),
109 .syscalls = { NULL }
110 };
111
112 #if __SIZEOF_POINTER__ > 4
113 static struct procabi linux32 = {
114 .type = "Linux32",
115 .abi = SYSDECODE_ABI_LINUX32,
116 .pointer_size = sizeof(uint32_t),
117 .extra_syscalls = STAILQ_HEAD_INITIALIZER(linux32.extra_syscalls),
118 .syscalls = { NULL }
119 };
120 #endif
121
122 static struct procabi_table abis[] = {
123 #if __SIZEOF_POINTER__ == 4
124 { "FreeBSD ELF32", &freebsd },
125 #elif __SIZEOF_POINTER__ == 8
126 { "FreeBSD ELF64", &freebsd },
127 { "FreeBSD ELF32", &freebsd32 },
128 #else
129 #error "Unsupported pointer size"
130 #endif
131 #if defined(__powerpc64__)
132 { "FreeBSD ELF64 V2", &freebsd },
133 #endif
134 #if defined(__amd64__)
135 { "FreeBSD a.out", &freebsd32 },
136 #endif
137 #if defined(__i386__)
138 { "FreeBSD a.out", &freebsd },
139 #endif
140 #if __SIZEOF_POINTER__ >= 8
141 { "Linux ELF64", &linux },
142 { "Linux ELF32", &linux32 },
143 #else
144 { "Linux ELF32", &linux },
145 #endif
146 };
147
148 int
truss_ptrace(struct trussinfo * info,int req,struct procinfo * p,void * addr,int data)149 truss_ptrace(struct trussinfo *info, int req, struct procinfo *p, void *addr,
150 int data)
151 {
152 if (info->cap_mode)
153 return (pdptrace(req, p->pfd, -1, addr, data));
154 return (ptrace(req, p->pid, addr, data));
155 }
156
157 static int
truss_ptrace_lwp(struct trussinfo * info,int req,struct procinfo * p,lwpid_t lwpid,void * addr,int data)158 truss_ptrace_lwp(struct trussinfo *info, int req, struct procinfo *p,
159 lwpid_t lwpid, void *addr, int data)
160 {
161 if (info->cap_mode)
162 return (pdptrace(req, p->pfd, lwpid, addr, data));
163 return (ptrace(req, lwpid, addr, data));
164 }
165
166 static int
t_wait(struct trussinfo * info,int pid,int * status,int wflags)167 t_wait(struct trussinfo *info, int pid, int *status, int wflags)
168 {
169 if (info->cap_mode)
170 return (pdwait(pid, status, wflags, NULL, NULL));
171 return (waitpid(pid, status, wflags));
172 }
173
174 static int
truss_wait(struct trussinfo * info,struct procinfo * p,int * status,int wflags)175 truss_wait(struct trussinfo *info, struct procinfo *p, int *status,
176 int wflags)
177 {
178 if (info->cap_mode)
179 return (pdwait(p->pfd, status, wflags, NULL, NULL));
180 return (waitpid(p->pid, status, wflags));
181 }
182
183 int
truss_kill(struct trussinfo * info,struct procinfo * p,int sig)184 truss_kill(struct trussinfo *info, struct procinfo *p, int sig)
185 {
186 if (info->cap_mode)
187 return (pdkill(p->pfd, sig));
188 return (kill(p->pid, sig));
189 }
190
191 /*
192 * setup_and_wait() is called to start a process. All it really does
193 * is fork(), enable tracing in the child, and then exec the given
194 * command. At that point, the child process stops, and the parent
195 * can wake up and deal with it.
196 */
197 void
setup_and_wait(struct trussinfo * info,char * command[])198 setup_and_wait(struct trussinfo *info, char *command[])
199 {
200 pid_t pid;
201 int fd, res;
202
203 if (info->cap_mode) {
204 pid = pdfork(&fd, PD_DAEMON | PD_CLOEXEC | PD_PTRACE_CAP);
205 if (pid == -1)
206 err(1, "fork failed");
207 } else {
208 pid = vfork();
209 fd = -1;
210 }
211 if (pid == 0) { /* Child */
212 ptrace(PT_TRACE_ME, 0, 0, 0);
213 execvp(command[0], command);
214 err(1, "execvp %s", command[0]);
215 }
216
217 if (info->cap_mode) {
218 if (caph_enter() == -1)
219 err(1, "cap_enter");
220 new_proc_register_kev(info, fd);
221 }
222
223 /* Only in the parent here */
224 res = t_wait(info, info->cap_mode ? fd : pid, NULL, WFLAGS);
225 if (res < 0)
226 err(1, "unexpected stop in waitpid");
227
228 new_proc(info, pid, 0, fd, false, false);
229 }
230
231 /*
232 * start_tracing is called to attach to an existing process.
233 */
234 void
start_tracing(struct trussinfo * info,pid_t pid)235 start_tracing(struct trussinfo *info, pid_t pid)
236 {
237 int fd, ret, retry;
238
239 if (info->cap_mode) {
240 fd = pdopenpid(pid, PD_DAEMON | PD_CLOEXEC | PD_PTRACE_CAP);
241 if (fd == -1)
242 err(1, "Cannot open the target process");
243 if (caph_enter() == -1)
244 err(1, "cap_enter");
245 new_proc_register_kev(info, fd);
246 } else {
247 fd = -1;
248 }
249
250 retry = 10;
251 do {
252 ret = info->cap_mode ? pdptrace(PT_ATTACH, fd, -1,
253 NULL, 0) : ptrace(PT_ATTACH, pid, NULL, 0);
254 usleep(200);
255 } while (ret && retry-- > 0);
256 if (ret)
257 err(1, "Cannot attach to target process");
258
259 ret = t_wait(info, info->cap_mode ? fd : pid, NULL, WFLAGS);
260 if (ret < 0)
261 err(1, "Unexpected stop in waitpid");
262
263 new_proc(info, pid, 0, fd, false, false);
264 }
265
266 /*
267 * Restore a process back to it's pre-truss state.
268 * Called for SIGINT, SIGTERM, SIGQUIT. This only
269 * applies if truss was told to monitor an already-existing
270 * process.
271 */
272 void
restore_proc(int signo __unused)273 restore_proc(int signo __unused)
274 {
275
276 detaching = 1;
277 }
278
279 static void
detach_proc(struct trussinfo * info,struct procinfo * p)280 detach_proc(struct trussinfo *info, struct procinfo *p)
281 {
282 int error, sig, status;
283
284 /*
285 * Stop the child so that we can detach. Filter out possible
286 * lingering SIGTRAP events buffered in the threads.
287 */
288 truss_kill(info, p, SIGSTOP);
289 for (;;) {
290 error = truss_wait(info, p, &status, WFLAGS);
291 if (error < 0)
292 err(1, "Unexpected error in waitpid");
293 sig = WIFSTOPPED(status) ? WSTOPSIG(status) : 0;
294 if (sig == SIGSTOP)
295 break;
296 if (sig == SIGTRAP)
297 sig = 0;
298 if (truss_ptrace(info, PT_CONTINUE, p, (caddr_t)1, sig) < 0)
299 err(1, "Can not continue for detach");
300 }
301
302 if (truss_ptrace(info, PT_DETACH, p, (caddr_t)1, 0) < 0)
303 err(1, "Can not detach the process");
304
305 truss_kill(info, p, SIGCONT);
306 }
307
308 /*
309 * Determine the ABI. This is called after every exec, and when
310 * a process is first monitored.
311 */
312 static struct procabi *
find_abi(struct trussinfo * info,struct procinfo * p)313 find_abi(struct trussinfo *info, struct procinfo *p)
314 {
315 unsigned i;
316 char progt[32];
317
318 if (truss_ptrace(info, PT_GET_ABI_NAME, p, progt,
319 sizeof(progt)) == -1) {
320 warn("cannot get ABI for proc %ld", (long)p->pid);
321 return (NULL);
322 }
323
324 for (i = 0; i < nitems(abis); i++) {
325 if (strcmp(abis[i].name, progt) == 0)
326 return (abis[i].abi);
327 }
328 warnx("ABI %s for pid %ld is not supported", progt, (long)p->pid);
329 return (NULL);
330 }
331
332 static struct threadinfo *
new_thread(struct procinfo * p,lwpid_t lwpid)333 new_thread(struct procinfo *p, lwpid_t lwpid)
334 {
335 struct threadinfo *nt;
336
337 /*
338 * If this happens it means there is a bug in truss. Unfortunately
339 * this will kill any processes truss is attached to.
340 */
341 LIST_FOREACH(nt, &p->threadlist, entries) {
342 if (nt->tid == lwpid)
343 errx(1, "Duplicate thread for LWP %ld", (long)lwpid);
344 }
345
346 nt = calloc(1, sizeof(struct threadinfo));
347 if (nt == NULL)
348 err(1, "calloc() failed");
349 nt->proc = p;
350 nt->tid = lwpid;
351 LIST_INSERT_HEAD(&p->threadlist, nt, entries);
352 return (nt);
353 }
354
355 static void
free_thread(struct threadinfo * t)356 free_thread(struct threadinfo *t)
357 {
358
359 LIST_REMOVE(t, entries);
360 free(t);
361 }
362
363 static void
add_threads(struct trussinfo * info,struct procinfo * p)364 add_threads(struct trussinfo *info, struct procinfo *p)
365 {
366 struct ptrace_lwpinfo pl;
367 struct threadinfo *t;
368 lwpid_t *lwps;
369 int i, nlwps;
370
371 nlwps = truss_ptrace(info, PT_GETNUMLWPS, p, NULL, 0);
372 if (nlwps == -1)
373 err(1, "Unable to fetch number of LWPs");
374 assert(nlwps > 0);
375 lwps = calloc(nlwps, sizeof(*lwps));
376 nlwps = truss_ptrace(info, PT_GETLWPLIST, p, lwps, nlwps);
377 if (nlwps == -1)
378 err(1, "Unable to fetch LWP list");
379 for (i = 0; i < nlwps; i++) {
380 t = new_thread(p, lwps[i]);
381 if (truss_ptrace_lwp(info, PT_LWPINFO, p, lwps[i], &pl,
382 sizeof(pl)) == -1)
383 err(1, "ptrace(PT_LWPINFO)");
384 if (pl.pl_flags & PL_FLAG_SCE) {
385 info->curthread = t;
386 enter_syscall(info, t, &pl);
387 }
388 }
389 free(lwps);
390 }
391
392 static void
new_proc_register_kev(struct trussinfo * info,int pfd)393 new_proc_register_kev(struct trussinfo *info, int pfd)
394 {
395 struct kevent ev[1];
396 int error;
397
398 if (!info->cap_mode)
399 return;
400 EV_SET(&ev[0], pfd, EVFILT_PROCDESC, EV_ADD, NOTE_EXIT |
401 NOTE_PDSIGCHLD | NOTE_FORK, 0, 0);
402 error = kevent(info->pdkq, ev, nitems(ev), NULL, 0, NULL);
403 if (error == -1)
404 err(1, "Unable to register pfd %d for notifications", pfd);
405 }
406
407 static bool
new_proc(struct trussinfo * info,pid_t pid,lwpid_t lwpid,int pfd,bool allow_known,bool wait_for)408 new_proc(struct trussinfo *info, pid_t pid, lwpid_t lwpid, int pfd,
409 bool allow_known, bool wait_for)
410 {
411 struct procinfo *np;
412
413 if (find_proc(info, pid) != NULL) {
414 if (allow_known)
415 return (false);
416
417 /*
418 * If this happens it means there is a bug in truss.
419 * Unfortunately this will kill any processes truss is
420 * attached to.
421 */
422 errx(1, "Duplicate process for pid %ld", (long)pid);
423 }
424 if (pfd == -1 && info->cap_mode) {
425 pfd = pdopenpid(pid, PD_DAEMON | PD_CLOEXEC | PD_PTRACE_CAP);
426 if (pfd == -1)
427 err(1, "pdopenpid %d", pid);
428 if (wait_for && t_wait(info, pfd, NULL, WFLAGS) < 0)
429 err(1, "waitpid on attach to %d", pid);
430 new_proc_register_kev(info, pfd);
431 }
432
433 np = calloc(1, sizeof(struct procinfo));
434 np->pid = pid;
435 np->pfd = pfd;
436 np->abi = find_abi(info, np);
437 np->herald_printed = false;
438 if ((info->flags & FOLLOWFORKS) != 0 && truss_ptrace(info,
439 PT_FOLLOW_FORK, np, NULL, 1) == -1)
440 err(1, "Unable to follow forks for pid %ld", (long)pid);
441 if (truss_ptrace(info, PT_LWP_EVENTS, np, NULL, 1) == -1)
442 err(1, "Unable to enable LWP events for pid %ld", (long)pid);
443 LIST_INIT(&np->threadlist);
444 LIST_INIT(&np->fdlist);
445 LIST_INSERT_HEAD(&info->proclist, np, entries);
446
447 if (lwpid != 0)
448 new_thread(np, lwpid);
449 else
450 add_threads(info, np);
451 return (true);
452 }
453
454 static void
free_proc(struct trussinfo * info,struct procinfo * p)455 free_proc(struct trussinfo *info, struct procinfo *p)
456 {
457 struct threadinfo *t, *t2;
458 struct fd_domain *f, *f2;
459 struct kevent ev[1];
460
461 if (info->cap_mode) {
462 EV_SET(&ev[0], p->pfd, EVFILT_PROCDESC, EV_DELETE, 0, 0, 0);
463 (void)kevent(info->pdkq, ev, nitems(ev), NULL, 0, 0);
464 close(p->pfd);
465 }
466
467 LIST_FOREACH_SAFE(t, &p->threadlist, entries, t2) {
468 free(t);
469 }
470
471 LIST_FOREACH_SAFE(f, &p->fdlist, entries, f2) {
472 free(f);
473 }
474
475 LIST_REMOVE(p, entries);
476 free(p);
477 }
478
479 static void
detach_all_procs(struct trussinfo * info)480 detach_all_procs(struct trussinfo *info)
481 {
482 struct procinfo *p, *p2;
483
484 LIST_FOREACH_SAFE(p, &info->proclist, entries, p2) {
485 detach_proc(info, p);
486 free_proc(info, p);
487 }
488 }
489
490 static struct procinfo *
find_proc(struct trussinfo * info,pid_t pid)491 find_proc(struct trussinfo *info, pid_t pid)
492 {
493 struct procinfo *np;
494
495 LIST_FOREACH(np, &info->proclist, entries) {
496 if (np->pid == pid)
497 return (np);
498 }
499
500 return (NULL);
501 }
502
503 /*
504 * Change curthread member based on (pid, lwpid).
505 */
506 static void
find_thread(struct trussinfo * info,pid_t pid,lwpid_t lwpid)507 find_thread(struct trussinfo *info, pid_t pid, lwpid_t lwpid)
508 {
509 struct procinfo *np;
510 struct threadinfo *nt;
511
512 np = find_proc(info, pid);
513 assert(np != NULL);
514
515 LIST_FOREACH(nt, &np->threadlist, entries) {
516 if (nt->tid == lwpid) {
517 info->curthread = nt;
518 return;
519 }
520 }
521 errx(1, "could not find thread");
522 }
523
524 /*
525 * When a process exits, it should have exactly one thread left.
526 * All of the other threads should have reported thread exit events.
527 */
528 static void
find_exit_thread(struct trussinfo * info,pid_t pid)529 find_exit_thread(struct trussinfo *info, pid_t pid)
530 {
531 struct procinfo *p;
532
533 p = find_proc(info, pid);
534 assert(p != NULL);
535
536 info->curthread = LIST_FIRST(&p->threadlist);
537 assert(info->curthread != NULL);
538 assert(LIST_NEXT(info->curthread, entries) == NULL);
539 }
540
541 static void
alloc_syscall(struct threadinfo * t,struct ptrace_lwpinfo * pl)542 alloc_syscall(struct threadinfo *t, struct ptrace_lwpinfo *pl)
543 {
544 u_int i;
545
546 assert(t->in_syscall == 0);
547 assert(t->cs.number == 0);
548 assert(t->cs.sc == NULL);
549 assert(t->cs.nargs == 0);
550 for (i = 0; i < nitems(t->cs.s_args); i++)
551 assert(t->cs.s_args[i] == NULL);
552 memset(t->cs.args, 0, sizeof(t->cs.args));
553 t->cs.number = pl->pl_syscall_code;
554 t->in_syscall = 1;
555 }
556
557 static void
free_syscall(struct threadinfo * t)558 free_syscall(struct threadinfo *t)
559 {
560 u_int i;
561
562 for (i = 0; i < t->cs.nargs; i++)
563 free(t->cs.s_args[i]);
564 memset(&t->cs, 0, sizeof(t->cs));
565 t->in_syscall = 0;
566 }
567
568 static void
enter_syscall(struct trussinfo * info,struct threadinfo * t,struct ptrace_lwpinfo * pl)569 enter_syscall(struct trussinfo *info, struct threadinfo *t,
570 struct ptrace_lwpinfo *pl)
571 {
572 struct syscall *sc;
573 u_int i, narg;
574
575 alloc_syscall(t, pl);
576 narg = MIN(pl->pl_syscall_narg, nitems(t->cs.args));
577 if (narg != 0 && truss_ptrace_lwp(info, PT_GET_SC_ARGS, t->proc,
578 t->tid, (caddr_t)t->cs.args, sizeof(t->cs.args)) != 0) {
579 free_syscall(t);
580 return;
581 }
582
583 sc = get_syscall(t, t->cs.number, narg);
584 if (sc->unknown && sc->trace)
585 fprintf(info->outfile, "-- UNKNOWN %s SYSCALL %d --\n",
586 t->proc->abi->type, t->cs.number);
587
588 t->cs.nargs = sc->decode.nargs;
589 assert(sc->decode.nargs <= nitems(t->cs.s_args));
590
591 t->cs.sc = sc;
592
593 /*
594 * A system call excluded by -t is never printed, so there is no
595 * point in formatting its arguments.
596 */
597 if (!sc->trace) {
598 clock_gettime(CLOCK_REALTIME, &t->before);
599 return;
600 }
601
602 /*
603 * At this point, we set up the system call arguments.
604 * We ignore any OUT ones, however -- those are arguments that
605 * are set by the system call, and so are probably meaningless
606 * now. This doesn't currently support arguments that are
607 * passed in *and* out, however.
608 */
609 #if DEBUG
610 fprintf(stderr, "syscall %s(", sc->name);
611 #endif
612 for (i = 0; i < t->cs.nargs; i++) {
613 #if DEBUG
614 fprintf(stderr, "0x%lx%s",
615 t->cs.args[sc->decode.args[i].offset],
616 i < (t->cs.nargs - 1) ? "," : "");
617 #endif
618 if (!(sc->decode.args[i].type & OUT)) {
619 t->cs.s_args[i] = print_arg(&sc->decode.args[i],
620 t->cs.args, NULL, info, &sc->decode);
621 }
622 }
623 #if DEBUG
624 fprintf(stderr, ")\n");
625 #endif
626
627 clock_gettime(CLOCK_REALTIME, &t->before);
628 }
629
630 /*
631 * When a thread exits voluntarily (including when a thread calls
632 * exit() to trigger a process exit), the thread's internal state
633 * holds the arguments passed to the exit system call. When the
634 * thread's exit is reported, log that system call without a return
635 * value.
636 */
637 static void
thread_exit_syscall(struct trussinfo * info)638 thread_exit_syscall(struct trussinfo *info)
639 {
640 struct threadinfo *t;
641
642 t = info->curthread;
643 if (!t->in_syscall)
644 return;
645
646 clock_gettime(CLOCK_REALTIME, &t->after);
647
648 print_syscall_ret(info, 0, NULL);
649 free_syscall(t);
650 }
651
652 static void
exit_syscall(struct trussinfo * info,struct ptrace_lwpinfo * pl)653 exit_syscall(struct trussinfo *info, struct ptrace_lwpinfo *pl)
654 {
655 struct threadinfo *t;
656 struct procinfo *p;
657 struct syscall *sc;
658 struct ptrace_sc_ret psr;
659 u_int i;
660
661 t = info->curthread;
662 if (!t->in_syscall)
663 return;
664
665 clock_gettime(CLOCK_REALTIME, &t->after);
666 p = t->proc;
667 if (truss_ptrace_lwp(info, PT_GET_SC_RET, p, t->tid, &psr,
668 sizeof(psr)) != 0) {
669 free_syscall(t);
670 return;
671 }
672
673 sc = t->cs.sc;
674 /*
675 * Here, we only look for arguments that have OUT masked in --
676 * otherwise, they were handled in enter_syscall(). A system call
677 * excluded by -t is never printed, so none of them are needed.
678 */
679 for (i = 0; i < sc->decode.nargs && sc->trace; i++) {
680 char *temp;
681
682 if (sc->decode.args[i].type & OUT) {
683 /*
684 * If an error occurred, then don't bother
685 * getting the data; it may not be valid.
686 */
687 if (psr.sr_error != 0) {
688 asprintf(&temp, "0x%lx",
689 (long)t->cs.args[sc->decode.args[i].offset]);
690 } else {
691 temp = print_arg(&sc->decode.args[i],
692 t->cs.args, psr.sr_retval, info,
693 &sc->decode);
694 }
695 t->cs.s_args[i] = temp;
696 }
697 }
698
699 /*
700 * Track successfully created sockets so later syscalls using the
701 * returned file descriptor can be identified by socket domain.
702 */
703 if (strcmp(sc->name, "socket") == 0 &&
704 psr.sr_error == 0) {
705
706 struct fd_domain *f = calloc(1, sizeof(*f));
707
708 f->fd = (int)psr.sr_retval[0];
709 f->domain = (int)t->cs.args[0];
710 f->protocol = (int)t->cs.args[2];
711
712 LIST_INSERT_HEAD(&p->fdlist, f, entries);
713 }
714
715 if (strcmp(sc->name, "close") == 0 &&
716 psr.sr_error == 0) {
717
718 struct fd_domain *f, *f2;
719
720 LIST_FOREACH_SAFE(f, &p->fdlist, entries, f2) {
721 if (f->fd == (int)t->cs.args[0]) {
722 LIST_REMOVE(f, entries);
723 free(f);
724 }
725 }
726 }
727
728 print_syscall_ret(info, psr.sr_error, psr.sr_retval);
729 free_syscall(t);
730
731 /*
732 * If the process executed a new image, check the ABI. If the
733 * new ABI isn't supported, stop tracing this process.
734 */
735 if (pl->pl_flags & PL_FLAG_EXEC) {
736 assert(LIST_NEXT(LIST_FIRST(&p->threadlist), entries) == NULL);
737 p->abi = find_abi(info, p);
738 if (p->abi == NULL) {
739 if (truss_ptrace(info, PT_DETACH, p, (caddr_t)1, 0) < 0)
740 err(1, "Can not detach the process");
741 free_proc(info, p);
742 }
743 }
744 }
745
746 int
print_line_prefix(struct trussinfo * info)747 print_line_prefix(struct trussinfo *info)
748 {
749 struct timespec timediff;
750 struct threadinfo *t;
751 int len;
752
753 len = 0;
754 t = info->curthread;
755 if (info->flags & (FOLLOWFORKS | DISPLAYTIDS)) {
756 if (info->flags & FOLLOWFORKS)
757 len += fprintf(info->outfile, "%5d", t->proc->pid);
758 if ((info->flags & (FOLLOWFORKS | DISPLAYTIDS)) ==
759 (FOLLOWFORKS | DISPLAYTIDS))
760 len += fprintf(info->outfile, " ");
761 if (info->flags & DISPLAYTIDS)
762 len += fprintf(info->outfile, "%6d", t->tid);
763 len += fprintf(info->outfile, ": ");
764 }
765 if (info->flags & ABSOLUTETIMESTAMPS) {
766 timespecsub(&t->after, &info->start_time, &timediff);
767 len += fprintf(info->outfile, "%jd.%09ld ",
768 (intmax_t)timediff.tv_sec, timediff.tv_nsec);
769 }
770 if (info->flags & RELATIVETIMESTAMPS) {
771 timespecsub(&t->after, &t->before, &timediff);
772 len += fprintf(info->outfile, "%jd.%09ld ",
773 (intmax_t)timediff.tv_sec, timediff.tv_nsec);
774 }
775 return (len);
776 }
777
778 static void
report_thread_death(struct trussinfo * info)779 report_thread_death(struct trussinfo *info)
780 {
781 struct threadinfo *t;
782
783 t = info->curthread;
784 clock_gettime(CLOCK_REALTIME, &t->after);
785 print_line_prefix(info);
786 fprintf(info->outfile, "<thread %ld exited>\n", (long)t->tid);
787 }
788
789 static void
report_thread_birth(struct trussinfo * info)790 report_thread_birth(struct trussinfo *info)
791 {
792 struct threadinfo *t;
793
794 t = info->curthread;
795 clock_gettime(CLOCK_REALTIME, &t->after);
796 t->before = t->after;
797 print_line_prefix(info);
798 fprintf(info->outfile, "<new thread %ld>\n", (long)t->tid);
799 }
800
801 static void
report_exit(struct trussinfo * info,siginfo_t * si)802 report_exit(struct trussinfo *info, siginfo_t *si)
803 {
804 struct threadinfo *t;
805
806 t = info->curthread;
807 clock_gettime(CLOCK_REALTIME, &t->after);
808 print_line_prefix(info);
809 if (si->si_code == CLD_EXITED)
810 fprintf(info->outfile, "process exit, rval = %u\n",
811 si->si_status);
812 else
813 fprintf(info->outfile, "process killed, signal = %u%s\n",
814 si->si_status, si->si_code == CLD_DUMPED ?
815 " (core dumped)" : "");
816 }
817
818 static void
report_new_child(struct trussinfo * info)819 report_new_child(struct trussinfo *info)
820 {
821 struct threadinfo *t;
822
823 t = info->curthread;
824 if (t->proc->herald_printed)
825 return;
826 t->proc->herald_printed = true;
827 clock_gettime(CLOCK_REALTIME, &t->after);
828 t->before = t->after;
829 print_line_prefix(info);
830 fprintf(info->outfile, "<new process>\n");
831 }
832
833 void
decode_siginfo(FILE * fp,siginfo_t * si)834 decode_siginfo(FILE *fp, siginfo_t *si)
835 {
836 const char *str;
837
838 fprintf(fp, " code=");
839 str = sysdecode_sigcode(si->si_signo, si->si_code);
840 if (str == NULL)
841 fprintf(fp, "%d", si->si_code);
842 else
843 fprintf(fp, "%s", str);
844 switch (si->si_code) {
845 case SI_NOINFO:
846 break;
847 case SI_QUEUE:
848 fprintf(fp, " value=%p", si->si_value.sival_ptr);
849 /* FALLTHROUGH */
850 case SI_USER:
851 case SI_LWP:
852 fprintf(fp, " pid=%jd uid=%jd", (intmax_t)si->si_pid,
853 (intmax_t)si->si_uid);
854 break;
855 case SI_TIMER:
856 fprintf(fp, " value=%p", si->si_value.sival_ptr);
857 fprintf(fp, " timerid=%d", si->si_timerid);
858 fprintf(fp, " overrun=%d", si->si_overrun);
859 if (si->si_errno != 0)
860 fprintf(fp, " errno=%d", si->si_errno);
861 break;
862 case SI_ASYNCIO:
863 fprintf(fp, " value=%p", si->si_value.sival_ptr);
864 break;
865 case SI_MESGQ:
866 fprintf(fp, " value=%p", si->si_value.sival_ptr);
867 fprintf(fp, " mqd=%d", si->si_mqd);
868 break;
869 default:
870 switch (si->si_signo) {
871 case SIGILL:
872 case SIGFPE:
873 case SIGSEGV:
874 case SIGBUS:
875 fprintf(fp, " trapno=%d", si->si_trapno);
876 fprintf(fp, " addr=%p", si->si_addr);
877 break;
878 case SIGCHLD:
879 fprintf(fp, " pid=%jd uid=%jd", (intmax_t)si->si_pid,
880 (intmax_t)si->si_uid);
881 fprintf(fp, " status=%d", si->si_status);
882 break;
883 }
884 }
885 }
886
887 static void
report_signal(struct trussinfo * info,siginfo_t * si,struct ptrace_lwpinfo * pl)888 report_signal(struct trussinfo *info, siginfo_t *si, struct ptrace_lwpinfo *pl)
889 {
890 struct threadinfo *t;
891 const char *signame;
892
893 t = info->curthread;
894 clock_gettime(CLOCK_REALTIME, &t->after);
895 print_line_prefix(info);
896 signame = sysdecode_signal(si->si_status);
897 if (signame == NULL)
898 signame = "?";
899 fprintf(info->outfile, "SIGNAL %u (%s)", si->si_status, signame);
900 if (pl->pl_event == PL_EVENT_SIGNAL && pl->pl_flags & PL_FLAG_SI)
901 decode_siginfo(info->outfile, &pl->pl_siginfo);
902 fprintf(info->outfile, "\n");
903
904 }
905
906 static void
eventloop_handle_trapped(struct trussinfo * info,pid_t si_pid,int si_status,siginfo_t * si)907 eventloop_handle_trapped(struct trussinfo *info, pid_t si_pid, int si_status,
908 siginfo_t *si)
909 {
910 struct procinfo *np;
911 struct ptrace_lwpinfo pl;
912 int pending_signal;
913
914 np = find_proc(info, si_pid);
915 if (np == NULL) {
916 new_proc(info, si_pid, 0, -1, true, false);
917 np = find_proc(info, si_pid);
918 }
919 if (truss_ptrace(info, PT_LWPINFO, np, &pl, sizeof(pl)) == -1)
920 err(1, "ptrace(PT_LWPINFO)");
921
922 if ((pl.pl_flags & PL_FLAG_CHILD) != 0) {
923 assert(LIST_FIRST(&info->proclist)->abi != NULL);
924 } else if ((pl.pl_flags & PL_FLAG_BORN) != 0) {
925 new_thread(np, pl.pl_lwpid);
926 }
927 find_thread(info, si_pid, pl.pl_lwpid);
928
929 pending_signal = 0;
930 if (si_status == SIGTRAP && (pl.pl_flags & (PL_FLAG_BORN |
931 PL_FLAG_EXITED | PL_FLAG_SCE | PL_FLAG_SCX)) != 0) {
932 if ((pl.pl_flags & PL_FLAG_BORN) != 0) {
933 if ((info->flags & COUNTONLY) == 0)
934 report_thread_birth(info);
935 } else if ((pl.pl_flags & PL_FLAG_EXITED) != 0) {
936 if ((info->flags & COUNTONLY) == 0)
937 report_thread_death(info);
938 free_thread(info->curthread);
939 info->curthread = NULL;
940 } else if ((pl.pl_flags & PL_FLAG_SCE) != 0) {
941 enter_syscall(info, info->curthread, &pl);
942 } else if ((pl.pl_flags & PL_FLAG_SCX) != 0) {
943 exit_syscall(info, &pl);
944 }
945 } else if ((pl.pl_flags & PL_FLAG_CHILD) != 0) {
946 if ((info->flags & COUNTONLY) == 0)
947 report_new_child(info);
948 } else if (si != NULL) {
949 if ((info->flags & NOSIGS) == 0)
950 report_signal(info, si, &pl);
951 pending_signal = si->si_status;
952 }
953 if (truss_ptrace(info, PT_SYSCALL, np, (caddr_t)1,
954 pending_signal) == -1)
955 err(1, "ptrace(PT_SYSCALL)");
956 }
957
958 static void
eventloop_handle_note_fork(struct trussinfo * info)959 eventloop_handle_note_fork(struct trussinfo *info)
960 {
961 struct ptrace_child *ptcs;
962 int cnt, i;
963
964 again:
965 cnt = ptrace(PT_GET_CHILDREN, getpid(), NULL, 0);
966 if (cnt == -1)
967 err(1, "Unexpected error from ptrace(PT_GET_CHILDREN) size");
968 if (cnt == 0)
969 return;
970 ptcs = calloc(cnt, sizeof(*ptcs));
971 if (ptcs == NULL)
972 err(1, "No memory");
973 cnt = ptrace(PT_GET_CHILDREN, getpid(), (caddr_t)ptcs,
974 cnt * sizeof(*ptcs));
975 if (cnt == -1) {
976 if (errno == ENOMEM) {
977 free(ptcs);
978 goto again;
979 }
980 err(1, "Unexpected error from ptrace(PT_GET_CHILDREN) data");
981 }
982 for (i = 0; i < cnt; i++) {
983 if ((ptcs[i].flags & (PTCHLD_TRACED | PTCHLD_TRACED_BY_ME |
984 PTCHLD_EXITED)) != (PTCHLD_TRACED | PTCHLD_TRACED_BY_ME))
985 continue;
986 if (new_proc(info, ptcs[i].pid, 0, -1, true, true)) {
987 if ((info->flags & COUNTONLY) == 0)
988 report_new_child(info);
989 eventloop_handle_trapped(info, ptcs[i].pid, SIGTRAP,
990 NULL);
991 }
992 }
993 free(ptcs);
994 }
995
996 /*
997 * Wait for events until all the processes have exited or truss has been
998 * asked to stop.
999 */
1000 void
eventloop(struct trussinfo * info)1001 eventloop(struct trussinfo *info)
1002 {
1003 siginfo_t si;
1004 struct kevent ev[1];
1005 int cnt, error;
1006 bool has_si;
1007
1008 while (!LIST_EMPTY(&info->proclist)) {
1009 if (detaching) {
1010 detach_all_procs(info);
1011 return;
1012 }
1013
1014 has_si = false;
1015 if (info->cap_mode) {
1016 cnt = kevent(info->pdkq, NULL, 0, ev, nitems(ev),
1017 NULL);
1018 if (cnt == -1) {
1019 if (errno == EINTR)
1020 continue;
1021 err(1, "Unexpected error from kevent");
1022 }
1023 if (cnt == 0) {
1024 /* XXXKIB ? */
1025 continue;
1026 }
1027 if ((ev[0].fflags & (NOTE_EXIT | NOTE_PDSIGCHLD)) !=
1028 0) {
1029 error = pdwait(ev[0].ident, NULL,
1030 WFLAGS | WNOHANG, NULL, &si);
1031 if (error == -1) {
1032 if (errno == EINTR ||
1033 errno == EWOULDBLOCK)
1034 continue;
1035 err(1, "Unexpected error from pdwait");
1036 }
1037 has_si = true;
1038
1039 /*
1040 * To get rid of zombie, we need to
1041 * waitpid() on it in addition to the
1042 * pdwait() above, because we are the
1043 * debugger, and the child was
1044 * reparented to us.
1045 */
1046 waitpid(si.si_pid, NULL, WEXITED | WNOHANG);
1047 }
1048 if ((ev[0].fflags & NOTE_FORK) != 0)
1049 eventloop_handle_note_fork(info);
1050 } else {
1051 if (waitid(P_ALL, 0, &si, WTRAPPED | WEXITED) == -1) {
1052 if (errno == EINTR)
1053 continue;
1054 err(1, "Unexpected error from waitid");
1055 }
1056 has_si = true;
1057 }
1058 if (!has_si)
1059 continue;
1060
1061 assert(si.si_signo == SIGCHLD);
1062
1063 switch (si.si_code) {
1064 case CLD_EXITED:
1065 case CLD_KILLED:
1066 case CLD_DUMPED:
1067 find_exit_thread(info, si.si_pid);
1068 if ((info->flags & COUNTONLY) == 0) {
1069 if (si.si_code == CLD_EXITED)
1070 thread_exit_syscall(info);
1071 report_exit(info, &si);
1072 }
1073 free_proc(info, info->curthread->proc);
1074 info->curthread = NULL;
1075 break;
1076 case CLD_TRAPPED:
1077 eventloop_handle_trapped(info, si.si_pid,
1078 si.si_status, &si);
1079 break;
1080 case CLD_STOPPED:
1081 errx(1, "waitid reported CLD_STOPPED");
1082 case CLD_CONTINUED:
1083 break;
1084 }
1085 }
1086 }
1087