1 /*- 2 * Copyright (c) 1988, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 4. Neither the name of the University nor the names of its contributors 14 * may be used to endorse or promote products derived from this software 15 * without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30 #ifndef lint 31 static const char copyright[] = 32 "@(#) Copyright (c) 1988, 1993\n\ 33 The Regents of the University of California. All rights reserved.\n"; 34 #endif /* not lint */ 35 36 #ifndef lint 37 #if 0 38 static char sccsid[] = "@(#)kdump.c 8.1 (Berkeley) 6/6/93"; 39 #endif 40 #endif /* not lint */ 41 #include <sys/cdefs.h> 42 __FBSDID("$FreeBSD$"); 43 44 #define _KERNEL 45 extern int errno; 46 #include <sys/errno.h> 47 #undef _KERNEL 48 #include <sys/param.h> 49 #include <sys/capsicum.h> 50 #include <sys/errno.h> 51 #define _KERNEL 52 #include <sys/time.h> 53 #undef _KERNEL 54 #include <sys/uio.h> 55 #include <sys/ktrace.h> 56 #include <sys/ioctl.h> 57 #include <sys/socket.h> 58 #include <sys/stat.h> 59 #include <sys/sysent.h> 60 #include <sys/umtx.h> 61 #include <sys/un.h> 62 #include <sys/queue.h> 63 #include <sys/wait.h> 64 #ifdef HAVE_LIBCAPSICUM 65 #include <sys/nv.h> 66 #endif 67 #include <arpa/inet.h> 68 #include <netinet/in.h> 69 #include <ctype.h> 70 #include <err.h> 71 #include <grp.h> 72 #include <inttypes.h> 73 #ifdef HAVE_LIBCAPSICUM 74 #include <libcapsicum.h> 75 #include <libcapsicum_grp.h> 76 #include <libcapsicum_pwd.h> 77 #include <libcapsicum_service.h> 78 #endif 79 #include <locale.h> 80 #include <netdb.h> 81 #include <nl_types.h> 82 #include <pwd.h> 83 #include <stdio.h> 84 #include <stdlib.h> 85 #include <string.h> 86 #include <sysdecode.h> 87 #include <termios.h> 88 #include <time.h> 89 #include <unistd.h> 90 #include <vis.h> 91 #include "ktrace.h" 92 #include "kdump_subr.h" 93 94 u_int abidump(struct ktr_header *); 95 int fetchprocinfo(struct ktr_header *, u_int *); 96 int fread_tail(void *, int, int); 97 void dumpheader(struct ktr_header *); 98 void ktrsyscall(struct ktr_syscall *, u_int); 99 void ktrsysret(struct ktr_sysret *, u_int); 100 void ktrnamei(char *, int); 101 void hexdump(char *, int, int); 102 void visdump(char *, int, int); 103 void ktrgenio(struct ktr_genio *, int); 104 void ktrpsig(struct ktr_psig *); 105 void ktrcsw(struct ktr_csw *); 106 void ktrcsw_old(struct ktr_csw_old *); 107 void ktruser_malloc(void *); 108 void ktruser_rtld(int, void *); 109 void ktruser(int, void *); 110 void ktrcaprights(cap_rights_t *); 111 void ktrsockaddr(struct sockaddr *); 112 void ktrstat(struct stat *); 113 void ktrstruct(char *, size_t); 114 void ktrcapfail(struct ktr_cap_fail *); 115 void ktrfault(struct ktr_fault *); 116 void ktrfaultend(struct ktr_faultend *); 117 void limitfd(int fd); 118 void usage(void); 119 120 #define TIMESTAMP_NONE 0x0 121 #define TIMESTAMP_ABSOLUTE 0x1 122 #define TIMESTAMP_ELAPSED 0x2 123 #define TIMESTAMP_RELATIVE 0x4 124 125 extern const char *signames[], *syscallnames[]; 126 extern int nsyscalls; 127 128 static int timestamp, decimal, fancy = 1, suppressdata, tail, threads, maxdata, 129 resolv = 0, abiflag = 0, syscallno = 0; 130 static const char *tracefile = DEF_TRACEFILE; 131 static struct ktr_header ktr_header; 132 133 #define TIME_FORMAT "%b %e %T %Y" 134 #define eqs(s1, s2) (strcmp((s1), (s2)) == 0) 135 136 #define print_number(i,n,c) do { \ 137 if (decimal) \ 138 printf("%c%jd", c, (intmax_t)*i); \ 139 else \ 140 printf("%c%#jx", c, (uintmax_t)(u_register_t)*i); \ 141 i++; \ 142 n--; \ 143 c = ','; \ 144 } while (0) 145 146 #if defined(__amd64__) || defined(__i386__) 147 148 void linux_ktrsyscall(struct ktr_syscall *, u_int); 149 void linux_ktrsysret(struct ktr_sysret *, u_int); 150 extern const char *linux_syscallnames[]; 151 152 #include <linux_syscalls.c> 153 154 /* 155 * from linux.h 156 * Linux syscalls return negative errno's, we do positive and map them 157 */ 158 static int bsd_to_linux_errno[ELAST + 1] = { 159 -0, -1, -2, -3, -4, -5, -6, -7, -8, -9, 160 -10, -35, -12, -13, -14, -15, -16, -17, -18, -19, 161 -20, -21, -22, -23, -24, -25, -26, -27, -28, -29, 162 -30, -31, -32, -33, -34, -11,-115,-114, -88, -89, 163 -90, -91, -92, -93, -94, -95, -96, -97, -98, -99, 164 -100,-101,-102,-103,-104,-105,-106,-107,-108,-109, 165 -110,-111, -40, -36,-112,-113, -39, -11, -87,-122, 166 -116, -66, -6, -6, -6, -6, -6, -37, -38, -9, 167 -6, -6, -43, -42, -75,-125, -84, -95, -16, -74, 168 -72, -67, -71 169 }; 170 #endif 171 172 #if defined(__amd64__) 173 extern const char *linux32_syscallnames[]; 174 175 #include <linux32_syscalls.c> 176 #endif 177 178 struct proc_info 179 { 180 TAILQ_ENTRY(proc_info) info; 181 u_int sv_flags; 182 pid_t pid; 183 }; 184 185 static TAILQ_HEAD(trace_procs, proc_info) trace_procs; 186 187 #ifdef HAVE_LIBCAPSICUM 188 static cap_channel_t *cappwd, *capgrp; 189 #endif 190 191 static void 192 strerror_init(void) 193 { 194 195 /* 196 * Cache NLS data before entering capability mode. 197 * XXXPJD: There should be strerror_init() and strsignal_init() in libc. 198 */ 199 (void)catopen("libc", NL_CAT_LOCALE); 200 } 201 202 static void 203 localtime_init(void) 204 { 205 time_t ltime; 206 207 /* 208 * Allow localtime(3) to cache /etc/localtime content before entering 209 * capability mode. 210 * XXXPJD: There should be localtime_init() in libc. 211 */ 212 (void)time(<ime); 213 (void)localtime(<ime); 214 } 215 216 #ifdef HAVE_LIBCAPSICUM 217 static int 218 cappwdgrp_setup(cap_channel_t **cappwdp, cap_channel_t **capgrpp) 219 { 220 cap_channel_t *capcas, *cappwdloc, *capgrploc; 221 const char *cmds[1], *fields[1]; 222 223 capcas = cap_init(); 224 if (capcas == NULL) { 225 warn("unable to contact casperd"); 226 return (-1); 227 } 228 cappwdloc = cap_service_open(capcas, "system.pwd"); 229 capgrploc = cap_service_open(capcas, "system.grp"); 230 /* Casper capability no longer needed. */ 231 cap_close(capcas); 232 if (cappwdloc == NULL || capgrploc == NULL) { 233 if (cappwdloc == NULL) 234 warn("unable to open system.pwd service"); 235 if (capgrploc == NULL) 236 warn("unable to open system.grp service"); 237 exit(1); 238 } 239 /* Limit system.pwd to only getpwuid() function and pw_name field. */ 240 cmds[0] = "getpwuid"; 241 if (cap_pwd_limit_cmds(cappwdloc, cmds, 1) < 0) 242 err(1, "unable to limit system.pwd service"); 243 fields[0] = "pw_name"; 244 if (cap_pwd_limit_fields(cappwdloc, fields, 1) < 0) 245 err(1, "unable to limit system.pwd service"); 246 /* Limit system.grp to only getgrgid() function and gr_name field. */ 247 cmds[0] = "getgrgid"; 248 if (cap_grp_limit_cmds(capgrploc, cmds, 1) < 0) 249 err(1, "unable to limit system.grp service"); 250 fields[0] = "gr_name"; 251 if (cap_grp_limit_fields(capgrploc, fields, 1) < 0) 252 err(1, "unable to limit system.grp service"); 253 254 *cappwdp = cappwdloc; 255 *capgrpp = capgrploc; 256 return (0); 257 } 258 #endif /* HAVE_LIBCAPSICUM */ 259 260 int 261 main(int argc, char *argv[]) 262 { 263 int ch, ktrlen, size; 264 void *m; 265 int trpoints = ALL_POINTS; 266 int drop_logged; 267 pid_t pid = 0; 268 u_int sv_flags; 269 270 setlocale(LC_CTYPE, ""); 271 272 timestamp = TIMESTAMP_NONE; 273 274 while ((ch = getopt(argc,argv,"f:dElm:np:AHRrSsTt:")) != -1) 275 switch (ch) { 276 case 'A': 277 abiflag = 1; 278 break; 279 case 'f': 280 tracefile = optarg; 281 break; 282 case 'd': 283 decimal = 1; 284 break; 285 case 'l': 286 tail = 1; 287 break; 288 case 'm': 289 maxdata = atoi(optarg); 290 break; 291 case 'n': 292 fancy = 0; 293 break; 294 case 'p': 295 pid = atoi(optarg); 296 break; 297 case 'r': 298 resolv = 1; 299 break; 300 case 'S': 301 syscallno = 1; 302 break; 303 case 's': 304 suppressdata = 1; 305 break; 306 case 'E': 307 timestamp |= TIMESTAMP_ELAPSED; 308 break; 309 case 'H': 310 threads = 1; 311 break; 312 case 'R': 313 timestamp |= TIMESTAMP_RELATIVE; 314 break; 315 case 'T': 316 timestamp |= TIMESTAMP_ABSOLUTE; 317 break; 318 case 't': 319 trpoints = getpoints(optarg); 320 if (trpoints < 0) 321 errx(1, "unknown trace point in %s", optarg); 322 break; 323 default: 324 usage(); 325 } 326 327 if (argc > optind) 328 usage(); 329 330 m = malloc(size = 1025); 331 if (m == NULL) 332 errx(1, "%s", strerror(ENOMEM)); 333 if (!freopen(tracefile, "r", stdin)) 334 err(1, "%s", tracefile); 335 336 strerror_init(); 337 localtime_init(); 338 #ifdef HAVE_LIBCAPSICUM 339 if (resolv != 0) { 340 if (cappwdgrp_setup(&cappwd, &capgrp) < 0) { 341 cappwd = NULL; 342 capgrp = NULL; 343 } 344 } 345 if (resolv == 0 || (cappwd != NULL && capgrp != NULL)) { 346 if (cap_enter() < 0 && errno != ENOSYS) 347 err(1, "unable to enter capability mode"); 348 } 349 #else 350 if (resolv == 0) { 351 if (cap_enter() < 0 && errno != ENOSYS) 352 err(1, "unable to enter capability mode"); 353 } 354 #endif 355 limitfd(STDIN_FILENO); 356 limitfd(STDOUT_FILENO); 357 limitfd(STDERR_FILENO); 358 359 TAILQ_INIT(&trace_procs); 360 drop_logged = 0; 361 while (fread_tail(&ktr_header, sizeof(struct ktr_header), 1)) { 362 if (ktr_header.ktr_type & KTR_DROP) { 363 ktr_header.ktr_type &= ~KTR_DROP; 364 if (!drop_logged && threads) { 365 printf( 366 "%6jd %6jd %-8.*s Events dropped.\n", 367 (intmax_t)ktr_header.ktr_pid, 368 ktr_header.ktr_tid > 0 ? 369 (intmax_t)ktr_header.ktr_tid : 0, 370 MAXCOMLEN, ktr_header.ktr_comm); 371 drop_logged = 1; 372 } else if (!drop_logged) { 373 printf("%6jd %-8.*s Events dropped.\n", 374 (intmax_t)ktr_header.ktr_pid, MAXCOMLEN, 375 ktr_header.ktr_comm); 376 drop_logged = 1; 377 } 378 } 379 if (trpoints & (1<<ktr_header.ktr_type)) 380 if (pid == 0 || ktr_header.ktr_pid == pid || 381 ktr_header.ktr_tid == pid) 382 dumpheader(&ktr_header); 383 if ((ktrlen = ktr_header.ktr_len) < 0) 384 errx(1, "bogus length 0x%x", ktrlen); 385 if (ktrlen > size) { 386 m = realloc(m, ktrlen+1); 387 if (m == NULL) 388 errx(1, "%s", strerror(ENOMEM)); 389 size = ktrlen; 390 } 391 if (ktrlen && fread_tail(m, ktrlen, 1) == 0) 392 errx(1, "data too short"); 393 if (fetchprocinfo(&ktr_header, (u_int *)m) != 0) 394 continue; 395 sv_flags = abidump(&ktr_header); 396 if (pid && ktr_header.ktr_pid != pid && 397 ktr_header.ktr_tid != pid) 398 continue; 399 if ((trpoints & (1<<ktr_header.ktr_type)) == 0) 400 continue; 401 drop_logged = 0; 402 switch (ktr_header.ktr_type) { 403 case KTR_SYSCALL: 404 #if defined(__amd64__) || defined(__i386__) 405 if ((sv_flags & SV_ABI_MASK) == SV_ABI_LINUX) 406 linux_ktrsyscall((struct ktr_syscall *)m, 407 sv_flags); 408 else 409 #endif 410 ktrsyscall((struct ktr_syscall *)m, sv_flags); 411 break; 412 case KTR_SYSRET: 413 #if defined(__amd64__) || defined(__i386__) 414 if ((sv_flags & SV_ABI_MASK) == SV_ABI_LINUX) 415 linux_ktrsysret((struct ktr_sysret *)m, 416 sv_flags); 417 else 418 #endif 419 ktrsysret((struct ktr_sysret *)m, sv_flags); 420 break; 421 case KTR_NAMEI: 422 case KTR_SYSCTL: 423 ktrnamei(m, ktrlen); 424 break; 425 case KTR_GENIO: 426 ktrgenio((struct ktr_genio *)m, ktrlen); 427 break; 428 case KTR_PSIG: 429 ktrpsig((struct ktr_psig *)m); 430 break; 431 case KTR_CSW: 432 if (ktrlen == sizeof(struct ktr_csw_old)) 433 ktrcsw_old((struct ktr_csw_old *)m); 434 else 435 ktrcsw((struct ktr_csw *)m); 436 break; 437 case KTR_USER: 438 ktruser(ktrlen, m); 439 break; 440 case KTR_STRUCT: 441 ktrstruct(m, ktrlen); 442 break; 443 case KTR_CAPFAIL: 444 ktrcapfail((struct ktr_cap_fail *)m); 445 break; 446 case KTR_FAULT: 447 ktrfault((struct ktr_fault *)m); 448 break; 449 case KTR_FAULTEND: 450 ktrfaultend((struct ktr_faultend *)m); 451 break; 452 default: 453 printf("\n"); 454 break; 455 } 456 if (tail) 457 fflush(stdout); 458 } 459 return 0; 460 } 461 462 void 463 limitfd(int fd) 464 { 465 cap_rights_t rights; 466 unsigned long cmd; 467 468 cap_rights_init(&rights, CAP_FSTAT); 469 cmd = 0; 470 471 switch (fd) { 472 case STDIN_FILENO: 473 cap_rights_set(&rights, CAP_READ); 474 break; 475 case STDOUT_FILENO: 476 cap_rights_set(&rights, CAP_IOCTL, CAP_WRITE); 477 cmd = TIOCGETA; /* required by isatty(3) in printf(3) */ 478 break; 479 case STDERR_FILENO: 480 cap_rights_set(&rights, CAP_WRITE); 481 if (!suppressdata) { 482 cap_rights_set(&rights, CAP_IOCTL); 483 cmd = TIOCGWINSZ; 484 } 485 break; 486 default: 487 abort(); 488 } 489 490 if (cap_rights_limit(fd, &rights) < 0 && errno != ENOSYS) 491 err(1, "unable to limit rights for descriptor %d", fd); 492 if (cmd != 0 && cap_ioctls_limit(fd, &cmd, 1) < 0 && errno != ENOSYS) 493 err(1, "unable to limit ioctls for descriptor %d", fd); 494 } 495 496 int 497 fread_tail(void *buf, int size, int num) 498 { 499 int i; 500 501 while ((i = fread(buf, size, num, stdin)) == 0 && tail) { 502 sleep(1); 503 clearerr(stdin); 504 } 505 return (i); 506 } 507 508 int 509 fetchprocinfo(struct ktr_header *kth, u_int *flags) 510 { 511 struct proc_info *pi; 512 513 switch (kth->ktr_type) { 514 case KTR_PROCCTOR: 515 TAILQ_FOREACH(pi, &trace_procs, info) { 516 if (pi->pid == kth->ktr_pid) { 517 TAILQ_REMOVE(&trace_procs, pi, info); 518 break; 519 } 520 } 521 pi = malloc(sizeof(struct proc_info)); 522 if (pi == NULL) 523 errx(1, "%s", strerror(ENOMEM)); 524 pi->sv_flags = *flags; 525 pi->pid = kth->ktr_pid; 526 TAILQ_INSERT_TAIL(&trace_procs, pi, info); 527 return (1); 528 529 case KTR_PROCDTOR: 530 TAILQ_FOREACH(pi, &trace_procs, info) { 531 if (pi->pid == kth->ktr_pid) { 532 TAILQ_REMOVE(&trace_procs, pi, info); 533 free(pi); 534 break; 535 } 536 } 537 return (1); 538 } 539 540 return (0); 541 } 542 543 u_int 544 abidump(struct ktr_header *kth) 545 { 546 struct proc_info *pi; 547 const char *abi; 548 const char *arch; 549 u_int flags = 0; 550 551 TAILQ_FOREACH(pi, &trace_procs, info) { 552 if (pi->pid == kth->ktr_pid) { 553 flags = pi->sv_flags; 554 break; 555 } 556 } 557 558 if (abiflag == 0) 559 return (flags); 560 561 switch (flags & SV_ABI_MASK) { 562 case SV_ABI_LINUX: 563 abi = "L"; 564 break; 565 case SV_ABI_FREEBSD: 566 abi = "F"; 567 break; 568 default: 569 abi = "U"; 570 break; 571 } 572 573 if (flags != 0) { 574 if (flags & SV_LP64) 575 arch = "64"; 576 else 577 arch = "32"; 578 } else 579 arch = "00"; 580 581 printf("%s%s ", abi, arch); 582 583 return (flags); 584 } 585 586 void 587 dumpheader(struct ktr_header *kth) 588 { 589 static char unknown[64]; 590 static struct timeval prevtime, prevtime_e, temp; 591 const char *type; 592 const char *sign; 593 594 switch (kth->ktr_type) { 595 case KTR_SYSCALL: 596 type = "CALL"; 597 break; 598 case KTR_SYSRET: 599 type = "RET "; 600 break; 601 case KTR_NAMEI: 602 type = "NAMI"; 603 break; 604 case KTR_GENIO: 605 type = "GIO "; 606 break; 607 case KTR_PSIG: 608 type = "PSIG"; 609 break; 610 case KTR_CSW: 611 type = "CSW "; 612 break; 613 case KTR_USER: 614 type = "USER"; 615 break; 616 case KTR_STRUCT: 617 type = "STRU"; 618 break; 619 case KTR_SYSCTL: 620 type = "SCTL"; 621 break; 622 case KTR_PROCCTOR: 623 /* FALLTHROUGH */ 624 case KTR_PROCDTOR: 625 return; 626 case KTR_CAPFAIL: 627 type = "CAP "; 628 break; 629 case KTR_FAULT: 630 type = "PFLT"; 631 break; 632 case KTR_FAULTEND: 633 type = "PRET"; 634 break; 635 default: 636 sprintf(unknown, "UNKNOWN(%d)", kth->ktr_type); 637 type = unknown; 638 } 639 640 /* 641 * The ktr_tid field was previously the ktr_buffer field, which held 642 * the kernel pointer value for the buffer associated with data 643 * following the record header. It now holds a threadid, but only 644 * for trace files after the change. Older trace files still contain 645 * kernel pointers. Detect this and suppress the results by printing 646 * negative tid's as 0. 647 */ 648 if (threads) 649 printf("%6jd %6jd %-8.*s ", (intmax_t)kth->ktr_pid, 650 kth->ktr_tid > 0 ? (intmax_t)kth->ktr_tid : 0, 651 MAXCOMLEN, kth->ktr_comm); 652 else 653 printf("%6jd %-8.*s ", (intmax_t)kth->ktr_pid, MAXCOMLEN, 654 kth->ktr_comm); 655 if (timestamp) { 656 if (timestamp & TIMESTAMP_ABSOLUTE) { 657 printf("%jd.%06ld ", (intmax_t)kth->ktr_time.tv_sec, 658 kth->ktr_time.tv_usec); 659 } 660 if (timestamp & TIMESTAMP_ELAPSED) { 661 if (prevtime_e.tv_sec == 0) 662 prevtime_e = kth->ktr_time; 663 timevalsub(&kth->ktr_time, &prevtime_e); 664 printf("%jd.%06ld ", (intmax_t)kth->ktr_time.tv_sec, 665 kth->ktr_time.tv_usec); 666 timevaladd(&kth->ktr_time, &prevtime_e); 667 } 668 if (timestamp & TIMESTAMP_RELATIVE) { 669 if (prevtime.tv_sec == 0) 670 prevtime = kth->ktr_time; 671 temp = kth->ktr_time; 672 timevalsub(&kth->ktr_time, &prevtime); 673 if ((intmax_t)kth->ktr_time.tv_sec < 0) { 674 kth->ktr_time = prevtime; 675 prevtime = temp; 676 timevalsub(&kth->ktr_time, &prevtime); 677 sign = "-"; 678 } else { 679 prevtime = temp; 680 sign = ""; 681 } 682 printf("%s%jd.%06ld ", sign, (intmax_t)kth->ktr_time.tv_sec, 683 kth->ktr_time.tv_usec); 684 } 685 } 686 printf("%s ", type); 687 } 688 689 #include <sys/syscall.h> 690 #define KTRACE 691 #include <sys/kern/syscalls.c> 692 #undef KTRACE 693 int nsyscalls = sizeof (syscallnames) / sizeof (syscallnames[0]); 694 695 static void 696 ioctlname(unsigned long val) 697 { 698 const char *str; 699 700 str = sysdecode_ioctlname(val); 701 if (str != NULL) 702 printf("%s", str); 703 else if (decimal) 704 printf("%lu", val); 705 else 706 printf("%#lx", val); 707 } 708 709 void 710 ktrsyscall(struct ktr_syscall *ktr, u_int flags) 711 { 712 int narg = ktr->ktr_narg; 713 register_t *ip; 714 intmax_t arg; 715 716 if ((flags != 0 && ((flags & SV_ABI_MASK) != SV_ABI_FREEBSD)) || 717 (ktr->ktr_code >= nsyscalls || ktr->ktr_code < 0)) 718 printf("[%d]", ktr->ktr_code); 719 else { 720 printf("%s", syscallnames[ktr->ktr_code]); 721 if (syscallno) 722 printf("[%d]", ktr->ktr_code); 723 } 724 ip = &ktr->ktr_args[0]; 725 if (narg) { 726 char c = '('; 727 if (fancy && 728 (flags == 0 || (flags & SV_ABI_MASK) == SV_ABI_FREEBSD)) { 729 switch (ktr->ktr_code) { 730 case SYS_bindat: 731 case SYS_connectat: 732 case SYS_faccessat: 733 case SYS_fchmodat: 734 case SYS_fchownat: 735 case SYS_fstatat: 736 case SYS_futimesat: 737 case SYS_linkat: 738 case SYS_mkdirat: 739 case SYS_mkfifoat: 740 case SYS_mknodat: 741 case SYS_openat: 742 case SYS_readlinkat: 743 case SYS_renameat: 744 case SYS_unlinkat: 745 case SYS_utimensat: 746 putchar('('); 747 atfdname(*ip, decimal); 748 c = ','; 749 ip++; 750 narg--; 751 break; 752 } 753 switch (ktr->ktr_code) { 754 case SYS_ioctl: { 755 print_number(ip, narg, c); 756 putchar(c); 757 ioctlname(*ip); 758 c = ','; 759 ip++; 760 narg--; 761 break; 762 } 763 case SYS_ptrace: 764 putchar('('); 765 ptraceopname(*ip); 766 c = ','; 767 ip++; 768 narg--; 769 break; 770 case SYS_access: 771 case SYS_eaccess: 772 case SYS_faccessat: 773 print_number(ip, narg, c); 774 putchar(','); 775 accessmodename(*ip); 776 ip++; 777 narg--; 778 break; 779 case SYS_open: 780 case SYS_openat: 781 print_number(ip, narg, c); 782 putchar(','); 783 flagsandmodename(ip[0], ip[1], decimal); 784 ip += 2; 785 narg -= 2; 786 break; 787 case SYS_wait4: 788 print_number(ip, narg, c); 789 print_number(ip, narg, c); 790 /* 791 * A flags value of zero is valid for 792 * wait4() but not for wait6(), so 793 * handle zero special here. 794 */ 795 if (*ip == 0) { 796 print_number(ip, narg, c); 797 } else { 798 putchar(','); 799 wait6optname(*ip); 800 ip++; 801 narg--; 802 } 803 break; 804 case SYS_wait6: 805 putchar('('); 806 idtypename(*ip, decimal); 807 c = ','; 808 ip++; 809 narg--; 810 print_number(ip, narg, c); 811 print_number(ip, narg, c); 812 putchar(','); 813 wait6optname(*ip); 814 ip++; 815 narg--; 816 break; 817 case SYS_chmod: 818 case SYS_fchmod: 819 case SYS_lchmod: 820 print_number(ip, narg, c); 821 putchar(','); 822 modename(*ip); 823 ip++; 824 narg--; 825 break; 826 case SYS_mknod: 827 case SYS_mknodat: 828 print_number(ip, narg, c); 829 putchar(','); 830 modename(*ip); 831 ip++; 832 narg--; 833 break; 834 case SYS_getfsstat: 835 print_number(ip, narg, c); 836 print_number(ip, narg, c); 837 putchar(','); 838 getfsstatflagsname(*ip); 839 ip++; 840 narg--; 841 break; 842 case SYS_mount: 843 print_number(ip, narg, c); 844 print_number(ip, narg, c); 845 putchar(','); 846 mountflagsname(*ip); 847 ip++; 848 narg--; 849 break; 850 case SYS_unmount: 851 print_number(ip, narg, c); 852 putchar(','); 853 mountflagsname(*ip); 854 ip++; 855 narg--; 856 break; 857 case SYS_recvmsg: 858 case SYS_sendmsg: 859 print_number(ip, narg, c); 860 print_number(ip, narg, c); 861 putchar(','); 862 sendrecvflagsname(*ip); 863 ip++; 864 narg--; 865 break; 866 case SYS_recvfrom: 867 case SYS_sendto: 868 print_number(ip, narg, c); 869 print_number(ip, narg, c); 870 print_number(ip, narg, c); 871 putchar(','); 872 sendrecvflagsname(*ip); 873 ip++; 874 narg--; 875 break; 876 case SYS_chflags: 877 case SYS_fchflags: 878 case SYS_lchflags: 879 print_number(ip, narg, c); 880 putchar(','); 881 modename(*ip); 882 ip++; 883 narg--; 884 break; 885 case SYS_kill: 886 print_number(ip, narg, c); 887 putchar(','); 888 signame(*ip); 889 ip++; 890 narg--; 891 break; 892 case SYS_reboot: 893 putchar('('); 894 rebootoptname(*ip); 895 ip++; 896 narg--; 897 break; 898 case SYS_umask: 899 putchar('('); 900 modename(*ip); 901 ip++; 902 narg--; 903 break; 904 case SYS_msync: 905 print_number(ip, narg, c); 906 print_number(ip, narg, c); 907 putchar(','); 908 msyncflagsname(*ip); 909 ip++; 910 narg--; 911 break; 912 #ifdef SYS_freebsd6_mmap 913 case SYS_freebsd6_mmap: 914 print_number(ip, narg, c); 915 print_number(ip, narg, c); 916 putchar(','); 917 mmapprotname(*ip); 918 putchar(','); 919 ip++; 920 narg--; 921 mmapflagsname(*ip); 922 ip++; 923 narg--; 924 break; 925 #endif 926 case SYS_mmap: 927 print_number(ip, narg, c); 928 print_number(ip, narg, c); 929 putchar(','); 930 mmapprotname(*ip); 931 putchar(','); 932 ip++; 933 narg--; 934 mmapflagsname(*ip); 935 ip++; 936 narg--; 937 break; 938 case SYS_mprotect: 939 print_number(ip, narg, c); 940 print_number(ip, narg, c); 941 putchar(','); 942 mmapprotname(*ip); 943 ip++; 944 narg--; 945 break; 946 case SYS_madvise: 947 print_number(ip, narg, c); 948 print_number(ip, narg, c); 949 putchar(','); 950 madvisebehavname(*ip); 951 ip++; 952 narg--; 953 break; 954 case SYS_setpriority: 955 print_number(ip, narg, c); 956 print_number(ip, narg, c); 957 putchar(','); 958 prioname(*ip); 959 ip++; 960 narg--; 961 break; 962 case SYS_fcntl: 963 print_number(ip, narg, c); 964 putchar(','); 965 fcntlcmdname(ip[0], ip[1], decimal); 966 ip += 2; 967 narg -= 2; 968 break; 969 case SYS_socket: { 970 int sockdomain; 971 putchar('('); 972 sockdomain = *ip; 973 sockdomainname(sockdomain); 974 ip++; 975 narg--; 976 putchar(','); 977 socktypenamewithflags(*ip); 978 ip++; 979 narg--; 980 if (sockdomain == PF_INET || 981 sockdomain == PF_INET6) { 982 putchar(','); 983 sockipprotoname(*ip); 984 ip++; 985 narg--; 986 } 987 c = ','; 988 break; 989 } 990 case SYS_setsockopt: 991 case SYS_getsockopt: 992 print_number(ip, narg, c); 993 putchar(','); 994 sockoptlevelname(*ip, decimal); 995 if (*ip == SOL_SOCKET) { 996 ip++; 997 narg--; 998 putchar(','); 999 sockoptname(*ip); 1000 } 1001 ip++; 1002 narg--; 1003 break; 1004 #ifdef SYS_freebsd6_lseek 1005 case SYS_freebsd6_lseek: 1006 print_number(ip, narg, c); 1007 /* Hidden 'pad' argument, not in lseek(2) */ 1008 print_number(ip, narg, c); 1009 print_number(ip, narg, c); 1010 putchar(','); 1011 whencename(*ip); 1012 ip++; 1013 narg--; 1014 break; 1015 #endif 1016 case SYS_lseek: 1017 print_number(ip, narg, c); 1018 /* Hidden 'pad' argument, not in lseek(2) */ 1019 print_number(ip, narg, c); 1020 putchar(','); 1021 whencename(*ip); 1022 ip++; 1023 narg--; 1024 break; 1025 case SYS_flock: 1026 print_number(ip, narg, c); 1027 putchar(','); 1028 flockname(*ip); 1029 ip++; 1030 narg--; 1031 break; 1032 case SYS_mkfifo: 1033 case SYS_mkfifoat: 1034 case SYS_mkdir: 1035 case SYS_mkdirat: 1036 print_number(ip, narg, c); 1037 putchar(','); 1038 modename(*ip); 1039 ip++; 1040 narg--; 1041 break; 1042 case SYS_shutdown: 1043 print_number(ip, narg, c); 1044 putchar(','); 1045 shutdownhowname(*ip); 1046 ip++; 1047 narg--; 1048 break; 1049 case SYS_socketpair: 1050 putchar('('); 1051 sockdomainname(*ip); 1052 ip++; 1053 narg--; 1054 putchar(','); 1055 socktypenamewithflags(*ip); 1056 ip++; 1057 narg--; 1058 c = ','; 1059 break; 1060 case SYS_getrlimit: 1061 case SYS_setrlimit: 1062 putchar('('); 1063 rlimitname(*ip); 1064 ip++; 1065 narg--; 1066 c = ','; 1067 break; 1068 case SYS_quotactl: 1069 print_number(ip, narg, c); 1070 putchar(','); 1071 quotactlname(*ip); 1072 ip++; 1073 narg--; 1074 c = ','; 1075 break; 1076 case SYS_nfssvc: 1077 putchar('('); 1078 nfssvcname(*ip); 1079 ip++; 1080 narg--; 1081 c = ','; 1082 break; 1083 case SYS_rtprio: 1084 putchar('('); 1085 rtprioname(*ip); 1086 ip++; 1087 narg--; 1088 c = ','; 1089 break; 1090 case SYS___semctl: 1091 print_number(ip, narg, c); 1092 print_number(ip, narg, c); 1093 putchar(','); 1094 semctlname(*ip); 1095 ip++; 1096 narg--; 1097 break; 1098 case SYS_semget: 1099 print_number(ip, narg, c); 1100 print_number(ip, narg, c); 1101 putchar(','); 1102 semgetname(*ip); 1103 ip++; 1104 narg--; 1105 break; 1106 case SYS_msgctl: 1107 print_number(ip, narg, c); 1108 putchar(','); 1109 shmctlname(*ip); 1110 ip++; 1111 narg--; 1112 break; 1113 case SYS_shmat: 1114 print_number(ip, narg, c); 1115 print_number(ip, narg, c); 1116 putchar(','); 1117 shmatname(*ip); 1118 ip++; 1119 narg--; 1120 break; 1121 case SYS_shmctl: 1122 print_number(ip, narg, c); 1123 putchar(','); 1124 shmctlname(*ip); 1125 ip++; 1126 narg--; 1127 break; 1128 case SYS_shm_open: 1129 print_number(ip, narg, c); 1130 putchar(','); 1131 flagsname(ip[0]); 1132 printf(",0%o", (unsigned int)ip[1]); 1133 ip += 3; 1134 narg -= 3; 1135 break; 1136 case SYS_minherit: 1137 print_number(ip, narg, c); 1138 print_number(ip, narg, c); 1139 putchar(','); 1140 minheritname(*ip); 1141 ip++; 1142 narg--; 1143 break; 1144 case SYS_rfork: 1145 putchar('('); 1146 rforkname(*ip); 1147 ip++; 1148 narg--; 1149 c = ','; 1150 break; 1151 case SYS_lio_listio: 1152 putchar('('); 1153 lio_listioname(*ip); 1154 ip++; 1155 narg--; 1156 c = ','; 1157 break; 1158 case SYS_mlockall: 1159 putchar('('); 1160 mlockallname(*ip); 1161 ip++; 1162 narg--; 1163 break; 1164 case SYS_sched_setscheduler: 1165 print_number(ip, narg, c); 1166 putchar(','); 1167 schedpolicyname(*ip); 1168 ip++; 1169 narg--; 1170 break; 1171 case SYS_sched_get_priority_max: 1172 case SYS_sched_get_priority_min: 1173 putchar('('); 1174 schedpolicyname(*ip); 1175 ip++; 1176 narg--; 1177 break; 1178 case SYS_sendfile: 1179 print_number(ip, narg, c); 1180 print_number(ip, narg, c); 1181 print_number(ip, narg, c); 1182 print_number(ip, narg, c); 1183 print_number(ip, narg, c); 1184 print_number(ip, narg, c); 1185 putchar(','); 1186 sendfileflagsname(*(int *)ip); 1187 ip++; 1188 narg--; 1189 break; 1190 case SYS_kldsym: 1191 print_number(ip, narg, c); 1192 putchar(','); 1193 kldsymcmdname(*ip); 1194 ip++; 1195 narg--; 1196 break; 1197 case SYS_sigprocmask: 1198 putchar('('); 1199 sigprocmaskhowname(*ip); 1200 ip++; 1201 narg--; 1202 c = ','; 1203 break; 1204 case SYS___acl_get_file: 1205 case SYS___acl_set_file: 1206 case SYS___acl_get_fd: 1207 case SYS___acl_set_fd: 1208 case SYS___acl_delete_file: 1209 case SYS___acl_delete_fd: 1210 case SYS___acl_aclcheck_file: 1211 case SYS___acl_aclcheck_fd: 1212 case SYS___acl_get_link: 1213 case SYS___acl_set_link: 1214 case SYS___acl_delete_link: 1215 case SYS___acl_aclcheck_link: 1216 print_number(ip, narg, c); 1217 putchar(','); 1218 acltypename(*ip); 1219 ip++; 1220 narg--; 1221 break; 1222 case SYS_sigaction: 1223 putchar('('); 1224 signame(*ip); 1225 ip++; 1226 narg--; 1227 c = ','; 1228 break; 1229 case SYS_extattrctl: 1230 print_number(ip, narg, c); 1231 putchar(','); 1232 extattrctlname(*ip); 1233 ip++; 1234 narg--; 1235 break; 1236 case SYS_nmount: 1237 print_number(ip, narg, c); 1238 print_number(ip, narg, c); 1239 putchar(','); 1240 mountflagsname(*ip); 1241 ip++; 1242 narg--; 1243 break; 1244 case SYS_thr_create: 1245 print_number(ip, narg, c); 1246 print_number(ip, narg, c); 1247 putchar(','); 1248 thrcreateflagsname(*ip); 1249 ip++; 1250 narg--; 1251 break; 1252 case SYS_thr_kill: 1253 print_number(ip, narg, c); 1254 putchar(','); 1255 signame(*ip); 1256 ip++; 1257 narg--; 1258 break; 1259 case SYS_kldunloadf: 1260 print_number(ip, narg, c); 1261 putchar(','); 1262 kldunloadfflagsname(*ip); 1263 ip++; 1264 narg--; 1265 break; 1266 case SYS_linkat: 1267 case SYS_renameat: 1268 case SYS_symlinkat: 1269 print_number(ip, narg, c); 1270 putchar(','); 1271 atfdname(*ip, decimal); 1272 ip++; 1273 narg--; 1274 break; 1275 case SYS_cap_fcntls_limit: 1276 print_number(ip, narg, c); 1277 putchar(','); 1278 arg = *ip; 1279 ip++; 1280 narg--; 1281 capfcntlname(arg); 1282 break; 1283 case SYS_posix_fadvise: 1284 print_number(ip, narg, c); 1285 print_number(ip, narg, c); 1286 print_number(ip, narg, c); 1287 (void)putchar(','); 1288 fadvisebehavname((int)*ip); 1289 ip++; 1290 narg--; 1291 break; 1292 case SYS_procctl: 1293 putchar('('); 1294 idtypename(*ip, decimal); 1295 c = ','; 1296 ip++; 1297 narg--; 1298 print_number(ip, narg, c); 1299 putchar(','); 1300 procctlcmdname(*ip); 1301 ip++; 1302 narg--; 1303 break; 1304 case SYS__umtx_op: 1305 print_number(ip, narg, c); 1306 putchar(','); 1307 umtxopname(*ip); 1308 switch (*ip) { 1309 case UMTX_OP_CV_WAIT: 1310 ip++; 1311 narg--; 1312 putchar(','); 1313 umtxcvwaitflags(*ip); 1314 break; 1315 case UMTX_OP_RW_RDLOCK: 1316 ip++; 1317 narg--; 1318 putchar(','); 1319 umtxrwlockflags(*ip); 1320 break; 1321 } 1322 ip++; 1323 narg--; 1324 } 1325 } 1326 while (narg > 0) { 1327 print_number(ip, narg, c); 1328 } 1329 putchar(')'); 1330 } 1331 putchar('\n'); 1332 } 1333 1334 void 1335 ktrsysret(struct ktr_sysret *ktr, u_int flags) 1336 { 1337 register_t ret = ktr->ktr_retval; 1338 int error = ktr->ktr_error; 1339 int code = ktr->ktr_code; 1340 1341 if ((flags != 0 && ((flags & SV_ABI_MASK) != SV_ABI_FREEBSD)) || 1342 (code >= nsyscalls || code < 0)) 1343 printf("[%d] ", code); 1344 else { 1345 printf("%s", syscallnames[code]); 1346 if (syscallno) 1347 printf("[%d]", code); 1348 printf(" "); 1349 } 1350 1351 if (error == 0) { 1352 if (fancy) { 1353 printf("%ld", (long)ret); 1354 if (ret < 0 || ret > 9) 1355 printf("/%#lx", (unsigned long)ret); 1356 } else { 1357 if (decimal) 1358 printf("%ld", (long)ret); 1359 else 1360 printf("%#lx", (unsigned long)ret); 1361 } 1362 } else if (error == ERESTART) 1363 printf("RESTART"); 1364 else if (error == EJUSTRETURN) 1365 printf("JUSTRETURN"); 1366 else { 1367 printf("-1 errno %d", ktr->ktr_error); 1368 if (fancy) 1369 printf(" %s", strerror(ktr->ktr_error)); 1370 } 1371 putchar('\n'); 1372 } 1373 1374 void 1375 ktrnamei(char *cp, int len) 1376 { 1377 printf("\"%.*s\"\n", len, cp); 1378 } 1379 1380 void 1381 hexdump(char *p, int len, int screenwidth) 1382 { 1383 int n, i; 1384 int width; 1385 1386 width = 0; 1387 do { 1388 width += 2; 1389 i = 13; /* base offset */ 1390 i += (width / 2) + 1; /* spaces every second byte */ 1391 i += (width * 2); /* width of bytes */ 1392 i += 3; /* " |" */ 1393 i += width; /* each byte */ 1394 i += 1; /* "|" */ 1395 } while (i < screenwidth); 1396 width -= 2; 1397 1398 for (n = 0; n < len; n += width) { 1399 for (i = n; i < n + width; i++) { 1400 if ((i % width) == 0) { /* beginning of line */ 1401 printf(" 0x%04x", i); 1402 } 1403 if ((i % 2) == 0) { 1404 printf(" "); 1405 } 1406 if (i < len) 1407 printf("%02x", p[i] & 0xff); 1408 else 1409 printf(" "); 1410 } 1411 printf(" |"); 1412 for (i = n; i < n + width; i++) { 1413 if (i >= len) 1414 break; 1415 if (p[i] >= ' ' && p[i] <= '~') 1416 printf("%c", p[i]); 1417 else 1418 printf("."); 1419 } 1420 printf("|\n"); 1421 } 1422 if ((i % width) != 0) 1423 printf("\n"); 1424 } 1425 1426 void 1427 visdump(char *dp, int datalen, int screenwidth) 1428 { 1429 int col = 0; 1430 char *cp; 1431 int width; 1432 char visbuf[5]; 1433 1434 printf(" \""); 1435 col = 8; 1436 for (;datalen > 0; datalen--, dp++) { 1437 vis(visbuf, *dp, VIS_CSTYLE, *(dp+1)); 1438 cp = visbuf; 1439 /* 1440 * Keep track of printables and 1441 * space chars (like fold(1)). 1442 */ 1443 if (col == 0) { 1444 putchar('\t'); 1445 col = 8; 1446 } 1447 switch(*cp) { 1448 case '\n': 1449 col = 0; 1450 putchar('\n'); 1451 continue; 1452 case '\t': 1453 width = 8 - (col&07); 1454 break; 1455 default: 1456 width = strlen(cp); 1457 } 1458 if (col + width > (screenwidth-2)) { 1459 printf("\\\n\t"); 1460 col = 8; 1461 } 1462 col += width; 1463 do { 1464 putchar(*cp++); 1465 } while (*cp); 1466 } 1467 if (col == 0) 1468 printf(" "); 1469 printf("\"\n"); 1470 } 1471 1472 void 1473 ktrgenio(struct ktr_genio *ktr, int len) 1474 { 1475 int datalen = len - sizeof (struct ktr_genio); 1476 char *dp = (char *)ktr + sizeof (struct ktr_genio); 1477 static int screenwidth = 0; 1478 int i, binary; 1479 1480 printf("fd %d %s %d byte%s\n", ktr->ktr_fd, 1481 ktr->ktr_rw == UIO_READ ? "read" : "wrote", datalen, 1482 datalen == 1 ? "" : "s"); 1483 if (suppressdata) 1484 return; 1485 if (screenwidth == 0) { 1486 struct winsize ws; 1487 1488 if (fancy && ioctl(fileno(stderr), TIOCGWINSZ, &ws) != -1 && 1489 ws.ws_col > 8) 1490 screenwidth = ws.ws_col; 1491 else 1492 screenwidth = 80; 1493 } 1494 if (maxdata && datalen > maxdata) 1495 datalen = maxdata; 1496 1497 for (i = 0, binary = 0; i < datalen && binary == 0; i++) { 1498 if (dp[i] >= 32 && dp[i] < 127) 1499 continue; 1500 if (dp[i] == 10 || dp[i] == 13 || dp[i] == 0 || dp[i] == 9) 1501 continue; 1502 binary = 1; 1503 } 1504 if (binary) 1505 hexdump(dp, datalen, screenwidth); 1506 else 1507 visdump(dp, datalen, screenwidth); 1508 } 1509 1510 const char *signames[] = { 1511 "NULL", "HUP", "INT", "QUIT", "ILL", "TRAP", "IOT", /* 1 - 6 */ 1512 "EMT", "FPE", "KILL", "BUS", "SEGV", "SYS", /* 7 - 12 */ 1513 "PIPE", "ALRM", "TERM", "URG", "STOP", "TSTP", /* 13 - 18 */ 1514 "CONT", "CHLD", "TTIN", "TTOU", "IO", "XCPU", /* 19 - 24 */ 1515 "XFSZ", "VTALRM", "PROF", "WINCH", "29", "USR1", /* 25 - 30 */ 1516 "USR2", NULL, /* 31 - 32 */ 1517 }; 1518 1519 void 1520 ktrpsig(struct ktr_psig *psig) 1521 { 1522 if (psig->signo > 0 && psig->signo < NSIG) 1523 printf("SIG%s ", signames[psig->signo]); 1524 else 1525 printf("SIG %d ", psig->signo); 1526 if (psig->action == SIG_DFL) { 1527 printf("SIG_DFL code="); 1528 sigcodename(psig->signo, psig->code); 1529 putchar('\n'); 1530 } else { 1531 printf("caught handler=0x%lx mask=0x%x code=", 1532 (u_long)psig->action, psig->mask.__bits[0]); 1533 sigcodename(psig->signo, psig->code); 1534 putchar('\n'); 1535 } 1536 } 1537 1538 void 1539 ktrcsw_old(struct ktr_csw_old *cs) 1540 { 1541 printf("%s %s\n", cs->out ? "stop" : "resume", 1542 cs->user ? "user" : "kernel"); 1543 } 1544 1545 void 1546 ktrcsw(struct ktr_csw *cs) 1547 { 1548 printf("%s %s \"%s\"\n", cs->out ? "stop" : "resume", 1549 cs->user ? "user" : "kernel", cs->wmesg); 1550 } 1551 1552 void 1553 ktruser(int len, void *p) 1554 { 1555 unsigned char *cp; 1556 1557 if (sysdecode_utrace(stdout, p, len)) { 1558 printf("\n"); 1559 return; 1560 } 1561 1562 printf("%d ", len); 1563 cp = p; 1564 while (len--) 1565 if (decimal) 1566 printf(" %d", *cp++); 1567 else 1568 printf(" %02x", *cp++); 1569 printf("\n"); 1570 } 1571 1572 void 1573 ktrcaprights(cap_rights_t *rightsp) 1574 { 1575 1576 printf("cap_rights_t "); 1577 capname(rightsp); 1578 printf("\n"); 1579 } 1580 1581 void 1582 ktrsockaddr(struct sockaddr *sa) 1583 { 1584 /* 1585 TODO: Support additional address families 1586 #include <netnatm/natm.h> 1587 struct sockaddr_natm *natm; 1588 #include <netsmb/netbios.h> 1589 struct sockaddr_nb *nb; 1590 */ 1591 char addr[64]; 1592 1593 /* 1594 * note: ktrstruct() has already verified that sa points to a 1595 * buffer at least sizeof(struct sockaddr) bytes long and exactly 1596 * sa->sa_len bytes long. 1597 */ 1598 printf("struct sockaddr { "); 1599 sockfamilyname(sa->sa_family); 1600 printf(", "); 1601 1602 #define check_sockaddr_len(n) \ 1603 if (sa_##n.s##n##_len < sizeof(struct sockaddr_##n)) { \ 1604 printf("invalid"); \ 1605 break; \ 1606 } 1607 1608 switch(sa->sa_family) { 1609 case AF_INET: { 1610 struct sockaddr_in sa_in; 1611 1612 memset(&sa_in, 0, sizeof(sa_in)); 1613 memcpy(&sa_in, sa, sa->sa_len); 1614 check_sockaddr_len(in); 1615 inet_ntop(AF_INET, &sa_in.sin_addr, addr, sizeof addr); 1616 printf("%s:%u", addr, ntohs(sa_in.sin_port)); 1617 break; 1618 } 1619 case AF_INET6: { 1620 struct sockaddr_in6 sa_in6; 1621 1622 memset(&sa_in6, 0, sizeof(sa_in6)); 1623 memcpy(&sa_in6, sa, sa->sa_len); 1624 check_sockaddr_len(in6); 1625 getnameinfo((struct sockaddr *)&sa_in6, sizeof(sa_in6), 1626 addr, sizeof(addr), NULL, 0, NI_NUMERICHOST); 1627 printf("[%s]:%u", addr, htons(sa_in6.sin6_port)); 1628 break; 1629 } 1630 case AF_UNIX: { 1631 struct sockaddr_un sa_un; 1632 1633 memset(&sa_un, 0, sizeof(sa_un)); 1634 memcpy(&sa_un, sa, sa->sa_len); 1635 printf("%.*s", (int)sizeof(sa_un.sun_path), sa_un.sun_path); 1636 break; 1637 } 1638 default: 1639 printf("unknown address family"); 1640 } 1641 printf(" }\n"); 1642 } 1643 1644 void 1645 ktrstat(struct stat *statp) 1646 { 1647 char mode[12], timestr[PATH_MAX + 4]; 1648 struct passwd *pwd; 1649 struct group *grp; 1650 struct tm *tm; 1651 1652 /* 1653 * note: ktrstruct() has already verified that statp points to a 1654 * buffer exactly sizeof(struct stat) bytes long. 1655 */ 1656 printf("struct stat {"); 1657 printf("dev=%ju, ino=%ju, ", 1658 (uintmax_t)statp->st_dev, (uintmax_t)statp->st_ino); 1659 if (resolv == 0) 1660 printf("mode=0%jo, ", (uintmax_t)statp->st_mode); 1661 else { 1662 strmode(statp->st_mode, mode); 1663 printf("mode=%s, ", mode); 1664 } 1665 printf("nlink=%ju, ", (uintmax_t)statp->st_nlink); 1666 if (resolv == 0) { 1667 pwd = NULL; 1668 } else { 1669 #ifdef HAVE_LIBCAPSICUM 1670 if (cappwd != NULL) 1671 pwd = cap_getpwuid(cappwd, statp->st_uid); 1672 else 1673 #endif 1674 pwd = getpwuid(statp->st_uid); 1675 } 1676 if (pwd == NULL) 1677 printf("uid=%ju, ", (uintmax_t)statp->st_uid); 1678 else 1679 printf("uid=\"%s\", ", pwd->pw_name); 1680 if (resolv == 0) { 1681 grp = NULL; 1682 } else { 1683 #ifdef HAVE_LIBCAPSICUM 1684 if (capgrp != NULL) 1685 grp = cap_getgrgid(capgrp, statp->st_gid); 1686 else 1687 #endif 1688 grp = getgrgid(statp->st_gid); 1689 } 1690 if (grp == NULL) 1691 printf("gid=%ju, ", (uintmax_t)statp->st_gid); 1692 else 1693 printf("gid=\"%s\", ", grp->gr_name); 1694 printf("rdev=%ju, ", (uintmax_t)statp->st_rdev); 1695 printf("atime="); 1696 if (resolv == 0) 1697 printf("%jd", (intmax_t)statp->st_atim.tv_sec); 1698 else { 1699 tm = localtime(&statp->st_atim.tv_sec); 1700 strftime(timestr, sizeof(timestr), TIME_FORMAT, tm); 1701 printf("\"%s\"", timestr); 1702 } 1703 if (statp->st_atim.tv_nsec != 0) 1704 printf(".%09ld, ", statp->st_atim.tv_nsec); 1705 else 1706 printf(", "); 1707 printf("stime="); 1708 if (resolv == 0) 1709 printf("%jd", (intmax_t)statp->st_mtim.tv_sec); 1710 else { 1711 tm = localtime(&statp->st_mtim.tv_sec); 1712 strftime(timestr, sizeof(timestr), TIME_FORMAT, tm); 1713 printf("\"%s\"", timestr); 1714 } 1715 if (statp->st_mtim.tv_nsec != 0) 1716 printf(".%09ld, ", statp->st_mtim.tv_nsec); 1717 else 1718 printf(", "); 1719 printf("ctime="); 1720 if (resolv == 0) 1721 printf("%jd", (intmax_t)statp->st_ctim.tv_sec); 1722 else { 1723 tm = localtime(&statp->st_ctim.tv_sec); 1724 strftime(timestr, sizeof(timestr), TIME_FORMAT, tm); 1725 printf("\"%s\"", timestr); 1726 } 1727 if (statp->st_ctim.tv_nsec != 0) 1728 printf(".%09ld, ", statp->st_ctim.tv_nsec); 1729 else 1730 printf(", "); 1731 printf("birthtime="); 1732 if (resolv == 0) 1733 printf("%jd", (intmax_t)statp->st_birthtim.tv_sec); 1734 else { 1735 tm = localtime(&statp->st_birthtim.tv_sec); 1736 strftime(timestr, sizeof(timestr), TIME_FORMAT, tm); 1737 printf("\"%s\"", timestr); 1738 } 1739 if (statp->st_birthtim.tv_nsec != 0) 1740 printf(".%09ld, ", statp->st_birthtim.tv_nsec); 1741 else 1742 printf(", "); 1743 printf("size=%jd, blksize=%ju, blocks=%jd, flags=0x%x", 1744 (uintmax_t)statp->st_size, (uintmax_t)statp->st_blksize, 1745 (intmax_t)statp->st_blocks, statp->st_flags); 1746 printf(" }\n"); 1747 } 1748 1749 void 1750 ktrstruct(char *buf, size_t buflen) 1751 { 1752 char *name, *data; 1753 size_t namelen, datalen; 1754 int i; 1755 cap_rights_t rights; 1756 struct stat sb; 1757 struct sockaddr_storage ss; 1758 1759 for (name = buf, namelen = 0; 1760 namelen < buflen && name[namelen] != '\0'; 1761 ++namelen) 1762 /* nothing */; 1763 if (namelen == buflen) 1764 goto invalid; 1765 if (name[namelen] != '\0') 1766 goto invalid; 1767 data = buf + namelen + 1; 1768 datalen = buflen - namelen - 1; 1769 if (datalen == 0) 1770 goto invalid; 1771 /* sanity check */ 1772 for (i = 0; i < (int)namelen; ++i) 1773 if (!isalpha(name[i])) 1774 goto invalid; 1775 if (strcmp(name, "caprights") == 0) { 1776 if (datalen != sizeof(cap_rights_t)) 1777 goto invalid; 1778 memcpy(&rights, data, datalen); 1779 ktrcaprights(&rights); 1780 } else if (strcmp(name, "stat") == 0) { 1781 if (datalen != sizeof(struct stat)) 1782 goto invalid; 1783 memcpy(&sb, data, datalen); 1784 ktrstat(&sb); 1785 } else if (strcmp(name, "sockaddr") == 0) { 1786 if (datalen > sizeof(ss)) 1787 goto invalid; 1788 memcpy(&ss, data, datalen); 1789 if (datalen != ss.ss_len) 1790 goto invalid; 1791 ktrsockaddr((struct sockaddr *)&ss); 1792 } else { 1793 printf("unknown structure\n"); 1794 } 1795 return; 1796 invalid: 1797 printf("invalid record\n"); 1798 } 1799 1800 void 1801 ktrcapfail(struct ktr_cap_fail *ktr) 1802 { 1803 switch (ktr->cap_type) { 1804 case CAPFAIL_NOTCAPABLE: 1805 /* operation on fd with insufficient capabilities */ 1806 printf("operation requires "); 1807 capname(&ktr->cap_needed); 1808 printf(", descriptor holds "); 1809 capname(&ktr->cap_held); 1810 break; 1811 case CAPFAIL_INCREASE: 1812 /* requested more capabilities than fd already has */ 1813 printf("attempt to increase capabilities from "); 1814 capname(&ktr->cap_held); 1815 printf(" to "); 1816 capname(&ktr->cap_needed); 1817 break; 1818 case CAPFAIL_SYSCALL: 1819 /* called restricted syscall */ 1820 printf("disallowed system call"); 1821 break; 1822 case CAPFAIL_LOOKUP: 1823 /* used ".." in strict-relative mode */ 1824 printf("restricted VFS lookup"); 1825 break; 1826 default: 1827 printf("unknown capability failure: "); 1828 capname(&ktr->cap_needed); 1829 printf(" "); 1830 capname(&ktr->cap_held); 1831 break; 1832 } 1833 printf("\n"); 1834 } 1835 1836 void 1837 ktrfault(struct ktr_fault *ktr) 1838 { 1839 1840 printf("0x%jx ", (uintmax_t)ktr->vaddr); 1841 vmprotname(ktr->type); 1842 printf("\n"); 1843 } 1844 1845 void 1846 ktrfaultend(struct ktr_faultend *ktr) 1847 { 1848 1849 vmresultname(ktr->result); 1850 printf("\n"); 1851 } 1852 1853 #if defined(__amd64__) || defined(__i386__) 1854 1855 #if defined(__amd64__) 1856 #define NLINUX_SYSCALLS(v) ((v) & SV_ILP32 ? \ 1857 nitems(linux32_syscallnames) : nitems(linux_syscallnames)) 1858 #define LINUX_SYSCALLNAMES(v, i) ((v) & SV_ILP32 ? \ 1859 linux32_syscallnames[i] : linux_syscallnames[i]) 1860 #else 1861 #define NLINUX_SYSCALLS(v) (nitems(linux_syscallnames)) 1862 #define LINUX_SYSCALLNAMES(v, i) (linux_syscallnames[i]) 1863 #endif 1864 1865 void 1866 linux_ktrsyscall(struct ktr_syscall *ktr, u_int sv_flags) 1867 { 1868 int narg = ktr->ktr_narg; 1869 unsigned code = ktr->ktr_code; 1870 register_t *ip; 1871 1872 if (ktr->ktr_code < 0 || code >= NLINUX_SYSCALLS(sv_flags)) 1873 printf("[%d]", ktr->ktr_code); 1874 else { 1875 printf("%s", LINUX_SYSCALLNAMES(sv_flags, ktr->ktr_code)); 1876 if (syscallno) 1877 printf("[%d]", ktr->ktr_code); 1878 } 1879 ip = &ktr->ktr_args[0]; 1880 if (narg) { 1881 char c = '('; 1882 while (narg > 0) 1883 print_number(ip, narg, c); 1884 putchar(')'); 1885 } 1886 putchar('\n'); 1887 } 1888 1889 void 1890 linux_ktrsysret(struct ktr_sysret *ktr, u_int sv_flags) 1891 { 1892 register_t ret = ktr->ktr_retval; 1893 unsigned code = ktr->ktr_code; 1894 int error = ktr->ktr_error; 1895 1896 if (ktr->ktr_code < 0 || code >= NLINUX_SYSCALLS(sv_flags)) 1897 printf("[%d] ", ktr->ktr_code); 1898 else { 1899 printf("%s ", LINUX_SYSCALLNAMES(sv_flags, code)); 1900 if (syscallno) 1901 printf("[%d]", code); 1902 printf(" "); 1903 } 1904 1905 if (error == 0) { 1906 if (fancy) { 1907 printf("%ld", (long)ret); 1908 if (ret < 0 || ret > 9) 1909 printf("/%#lx", (unsigned long)ret); 1910 } else { 1911 if (decimal) 1912 printf("%ld", (long)ret); 1913 else 1914 printf("%#lx", (unsigned long)ret); 1915 } 1916 } else if (error == ERESTART) 1917 printf("RESTART"); 1918 else if (error == EJUSTRETURN) 1919 printf("JUSTRETURN"); 1920 else { 1921 if (ktr->ktr_error <= ELAST + 1) 1922 error = abs(bsd_to_linux_errno[ktr->ktr_error]); 1923 else 1924 error = 999; 1925 printf("-1 errno %d", error); 1926 if (fancy) 1927 printf(" %s", strerror(ktr->ktr_error)); 1928 } 1929 putchar('\n'); 1930 } 1931 #endif 1932 1933 void 1934 usage(void) 1935 { 1936 fprintf(stderr, "usage: kdump [-dEnlHRrSsTA] [-f trfile] " 1937 "[-m maxdata] [-p pid] [-t trstr]\n"); 1938 exit(1); 1939 } 1940