diff options
author | Simon J. Gerraty <sjg@FreeBSD.org> | 2014-04-28 07:50:45 +0000 |
---|---|---|
committer | Simon J. Gerraty <sjg@FreeBSD.org> | 2014-04-28 07:50:45 +0000 |
commit | 3b8f08459569bf0faa21473e5cec2491e95c9349 (patch) | |
tree | 80f45dd81ca716bcd7ca9674581e1fc40b93cd34 /usr.bin/kdump | |
parent | 9d2ab4a62d6733c45958627ac113bdbd818d1e2a (diff) | |
parent | b2ba55951383498f252746f618d513139da06e8e (diff) | |
download | src-3b8f08459569bf0faa21473e5cec2491e95c9349.tar.gz src-3b8f08459569bf0faa21473e5cec2491e95c9349.zip |
Notes
Diffstat (limited to 'usr.bin/kdump')
-rw-r--r-- | usr.bin/kdump/Makefile | 12 | ||||
-rw-r--r-- | usr.bin/kdump/kdump.1 | 6 | ||||
-rw-r--r-- | usr.bin/kdump/kdump.c | 209 | ||||
-rw-r--r-- | usr.bin/kdump/mkioctls | 6 | ||||
-rw-r--r-- | usr.bin/kdump/mksubr | 6 |
5 files changed, 172 insertions, 67 deletions
diff --git a/usr.bin/kdump/Makefile b/usr.bin/kdump/Makefile index ba81083e94ce..0e52763d3760 100644 --- a/usr.bin/kdump/Makefile +++ b/usr.bin/kdump/Makefile @@ -1,6 +1,8 @@ # @(#)Makefile 8.1 (Berkeley) 6/6/93 # $FreeBSD$ +.include <bsd.own.mk> + .if (${MACHINE_ARCH} == "amd64") SFX= 32 .endif @@ -12,6 +14,16 @@ SRCS= kdump_subr.c kdump.c ioctl.c subr.c DPSRCS= kdump_subr.h CFLAGS+= -I${.CURDIR}/../ktrace -I${.CURDIR} -I${.CURDIR}/../.. -I. +.if ${MK_CASPER} != "no" +DPADD+= ${LIBCAPSICUM} ${LIBNV} +LDADD+= -lcapsicum -lnv +CFLAGS+=-DHAVE_LIBCAPSICUM +.endif + +.if ${MK_PF} != "no" +CFLAGS+=-DPF +.endif + .if ${MACHINE_ARCH} == "amd64" || ${MACHINE_ARCH} == "i386" SRCS+= linux_syscalls.c .endif diff --git a/usr.bin/kdump/kdump.1 b/usr.bin/kdump/kdump.1 index f8e87e410ace..a3cc1cf9dfe6 100644 --- a/usr.bin/kdump/kdump.1 +++ b/usr.bin/kdump/kdump.1 @@ -28,7 +28,7 @@ .\" @(#)kdump.1 8.1 (Berkeley) 6/6/93 .\" $FreeBSD$ .\" -.Dd June 4, 2012 +.Dd March 28, 2014 .Dt KDUMP 1 .Os .Sh NAME @@ -36,7 +36,7 @@ .Nd display kernel trace data .Sh SYNOPSIS .Nm -.Op Fl dEnlHRsTA +.Op Fl dEnlHRSsTA .Op Fl f Ar trfile .Op Fl m Ar maxdata .Op Fl p Ar pid @@ -95,6 +95,8 @@ Display relative timestamps (time since previous entry). .It Fl r When decoding STRU records, display structure members such as UIDs, GIDs, dates etc. symbolically instead of numerically. +.It Fl S +Display system call numbers. .It Fl s Suppress display of I/O data. .It Fl T diff --git a/usr.bin/kdump/kdump.c b/usr.bin/kdump/kdump.c index 24bb0fd34e03..f6e1c794ce90 100644 --- a/usr.bin/kdump/kdump.c +++ b/usr.bin/kdump/kdump.c @@ -46,7 +46,7 @@ extern int errno; #include <sys/errno.h> #undef _KERNEL #include <sys/param.h> -#include <sys/capability.h> +#include <sys/capsicum.h> #include <sys/errno.h> #define _KERNEL #include <sys/time.h> @@ -60,13 +60,6 @@ extern int errno; #include <sys/un.h> #include <sys/queue.h> #include <sys/wait.h> -#ifdef IPX -#include <sys/types.h> -#include <netipx/ipx.h> -#endif -#ifdef NETATALK -#include <netatalk/at.h> -#endif #include <arpa/inet.h> #include <netinet/in.h> #include <ctype.h> @@ -74,9 +67,18 @@ extern int errno; #include <err.h> #include <grp.h> #include <inttypes.h> +#ifdef HAVE_LIBCAPSICUM +#include <libcapsicum.h> +#include <libcapsicum_grp.h> +#include <libcapsicum_pwd.h> +#include <libcapsicum_service.h> +#endif #include <locale.h> #include <netdb.h> #include <nl_types.h> +#ifdef HAVE_LIBCAPSICUM +#include <nv.h> +#endif #include <pwd.h> #include <stdio.h> #include <stdlib.h> @@ -115,8 +117,13 @@ void limitfd(int fd); void usage(void); void ioctlname(unsigned long, int); +#define TIMESTAMP_NONE 0x0 +#define TIMESTAMP_ABSOLUTE 0x1 +#define TIMESTAMP_ELAPSED 0x2 +#define TIMESTAMP_RELATIVE 0x4 + int timestamp, decimal, fancy = 1, suppressdata, tail, threads, maxdata, - resolv = 0, abiflag = 0; + resolv = 0, abiflag = 0, syscallno = 0; const char *tracefile = DEF_TRACEFILE; struct ktr_header ktr_header; @@ -167,6 +174,10 @@ struct proc_info TAILQ_HEAD(trace_procs, proc_info) trace_procs; +#ifdef HAVE_LIBCAPSICUM +static cap_channel_t *cappwd, *capgrp; +#endif + static void strerror_init(void) { @@ -192,6 +203,50 @@ localtime_init(void) (void)localtime(<ime); } +#ifdef HAVE_LIBCAPSICUM +static int +cappwdgrp_setup(cap_channel_t **cappwdp, cap_channel_t **capgrpp) +{ + cap_channel_t *capcas, *cappwdloc, *capgrploc; + const char *cmds[1], *fields[1]; + + capcas = cap_init(); + if (capcas == NULL) { + warn("unable to contact casperd"); + return (-1); + } + cappwdloc = cap_service_open(capcas, "system.pwd"); + capgrploc = cap_service_open(capcas, "system.grp"); + /* Casper capability no longer needed. */ + cap_close(capcas); + if (cappwdloc == NULL || capgrploc == NULL) { + if (cappwdloc == NULL) + warn("unable to open system.pwd service"); + if (capgrploc == NULL) + warn("unable to open system.grp service"); + exit(1); + } + /* Limit system.pwd to only getpwuid() function and pw_name field. */ + cmds[0] = "getpwuid"; + if (cap_pwd_limit_cmds(cappwdloc, cmds, 1) < 0) + err(1, "unable to limit system.pwd service"); + fields[0] = "pw_name"; + if (cap_pwd_limit_fields(cappwdloc, fields, 1) < 0) + err(1, "unable to limit system.pwd service"); + /* Limit system.grp to only getgrgid() function and gr_name field. */ + cmds[0] = "getgrgid"; + if (cap_grp_limit_cmds(capgrploc, cmds, 1) < 0) + err(1, "unable to limit system.grp service"); + fields[0] = "gr_name"; + if (cap_grp_limit_fields(capgrploc, fields, 1) < 0) + err(1, "unable to limit system.grp service"); + + *cappwdp = cappwdloc; + *capgrpp = capgrploc; + return (0); +} +#endif /* HAVE_LIBCAPSICUM */ + int main(int argc, char *argv[]) { @@ -204,7 +259,9 @@ main(int argc, char *argv[]) setlocale(LC_CTYPE, ""); - while ((ch = getopt(argc,argv,"f:dElm:np:AHRrsTt:")) != -1) + timestamp = TIMESTAMP_NONE; + + while ((ch = getopt(argc,argv,"f:dElm:np:AHRrSsTt:")) != -1) switch (ch) { case 'A': abiflag = 1; @@ -230,20 +287,23 @@ main(int argc, char *argv[]) case 'r': resolv = 1; break; + case 'S': + syscallno = 1; + break; case 's': suppressdata = 1; break; case 'E': - timestamp = 3; /* elapsed timestamp */ + timestamp |= TIMESTAMP_ELAPSED; break; case 'H': threads = 1; break; case 'R': - timestamp = 2; /* relative timestamp */ + timestamp |= TIMESTAMP_RELATIVE; break; case 'T': - timestamp = 1; + timestamp |= TIMESTAMP_ABSOLUTE; break; case 't': trpoints = getpoints(optarg); @@ -265,14 +325,28 @@ main(int argc, char *argv[]) strerror_init(); localtime_init(); - +#ifdef HAVE_LIBCAPSICUM + if (resolv != 0) { + if (cappwdgrp_setup(&cappwd, &capgrp) < 0) { + cappwd = NULL; + capgrp = NULL; + } + } + if (resolv == 0 || (cappwd != NULL && capgrp != NULL)) { + if (cap_enter() < 0 && errno != ENOSYS) + err(1, "unable to enter capability mode"); + } +#else if (resolv == 0) { if (cap_enter() < 0 && errno != ENOSYS) err(1, "unable to enter capability mode"); } +#endif limitfd(STDIN_FILENO); limitfd(STDOUT_FILENO); limitfd(STDERR_FILENO); + if (cap_sandboxed()) + fprintf(stderr, "capability mode sandbox enabled\n"); TAILQ_INIT(&trace_procs); drop_logged = 0; @@ -503,7 +577,7 @@ void dumpheader(struct ktr_header *kth) { static char unknown[64]; - static struct timeval prevtime, temp; + static struct timeval prevtime, prevtime_e, temp; const char *type; switch (kth->ktr_type) { @@ -567,19 +641,26 @@ dumpheader(struct ktr_header *kth) else printf("%6jd %-8.*s ", (intmax_t)kth->ktr_pid, MAXCOMLEN, kth->ktr_comm); - if (timestamp) { - if (timestamp == 3) { - if (prevtime.tv_sec == 0) - prevtime = kth->ktr_time; - timevalsub(&kth->ktr_time, &prevtime); + if (timestamp) { + if (timestamp & TIMESTAMP_ABSOLUTE) { + printf("%jd.%06ld ", (intmax_t)kth->ktr_time.tv_sec, + kth->ktr_time.tv_usec); + } + if (timestamp & TIMESTAMP_ELAPSED) { + if (prevtime_e.tv_sec == 0) + prevtime_e = kth->ktr_time; + timevalsub(&kth->ktr_time, &prevtime_e); + printf("%jd.%06ld ", (intmax_t)kth->ktr_time.tv_sec, + kth->ktr_time.tv_usec); + timevaladd(&kth->ktr_time, &prevtime_e); } - if (timestamp == 2) { + if (timestamp & TIMESTAMP_RELATIVE) { temp = kth->ktr_time; timevalsub(&kth->ktr_time, &prevtime); prevtime = temp; + printf("%jd.%06ld ", (intmax_t)kth->ktr_time.tv_sec, + kth->ktr_time.tv_usec); } - printf("%jd.%06ld ", (intmax_t)kth->ktr_time.tv_sec, - kth->ktr_time.tv_usec); } printf("%s ", type); } @@ -600,8 +681,11 @@ ktrsyscall(struct ktr_syscall *ktr, u_int flags) if ((flags != 0 && ((flags & SV_ABI_MASK) != SV_ABI_FREEBSD)) || (ktr->ktr_code >= nsyscalls || ktr->ktr_code < 0)) printf("[%d]", ktr->ktr_code); - else + else { printf("%s", syscallnames[ktr->ktr_code]); + if (syscallno) + printf("[%d]", ktr->ktr_code); + } ip = &ktr->ktr_args[0]; if (narg) { char c = '('; @@ -1193,8 +1277,12 @@ ktrsysret(struct ktr_sysret *ktr, u_int flags) if ((flags != 0 && ((flags & SV_ABI_MASK) != SV_ABI_FREEBSD)) || (code >= nsyscalls || code < 0)) printf("[%d] ", code); - else - printf("%s ", syscallnames[code]); + else { + printf("%s", syscallnames[code]); + if (syscallno) + printf("[%d]", code); + printf(" "); + } if (error == 0) { if (fancy) { @@ -1589,21 +1677,6 @@ ktrsockaddr(struct sockaddr *sa) printf("%s:%u", addr, ntohs(sa_in.sin_port)); break; } -#ifdef NETATALK - case AF_APPLETALK: { - struct sockaddr_at sa_at; - struct netrange *nr; - - memset(&sa_at, 0, sizeof(sa_at)); - memcpy(&sa_at, sa, sa->sa_len); - check_sockaddr_len(at); - nr = &sa_at.sat_range.r_netrange; - printf("%d.%d, %d-%d, %d", ntohs(sa_at.sat_addr.s_net), - sa_at.sat_addr.s_node, ntohs(nr->nr_firstnet), - ntohs(nr->nr_lastnet), nr->nr_phase); - break; - } -#endif case AF_INET6: { struct sockaddr_in6 sa_in6; @@ -1615,19 +1688,6 @@ ktrsockaddr(struct sockaddr *sa) printf("[%s]:%u", addr, htons(sa_in6.sin6_port)); break; } -#ifdef IPX - case AF_IPX: { - struct sockaddr_ipx sa_ipx; - - memset(&sa_ipx, 0, sizeof(sa_ipx)); - memcpy(&sa_ipx, sa, sa->sa_len); - check_sockaddr_len(ipx); - /* XXX wish we had ipx_ntop */ - printf("%s", ipx_ntoa(sa_ipx.sipx_addr)); - free(sa_ipx); - break; - } -#endif case AF_UNIX: { struct sockaddr_un sa_un; @@ -1664,11 +1724,31 @@ ktrstat(struct stat *statp) printf("mode=%s, ", mode); } printf("nlink=%ju, ", (uintmax_t)statp->st_nlink); - if (resolv == 0 || (pwd = getpwuid(statp->st_uid)) == NULL) + if (resolv == 0) { + pwd = NULL; + } else { +#ifdef HAVE_LIBCAPSICUM + if (cappwd != NULL) + pwd = cap_getpwuid(cappwd, statp->st_uid); + else +#endif + pwd = getpwuid(statp->st_uid); + } + if (pwd == NULL) printf("uid=%ju, ", (uintmax_t)statp->st_uid); else printf("uid=\"%s\", ", pwd->pw_name); - if (resolv == 0 || (grp = getgrgid(statp->st_gid)) == NULL) + if (resolv == 0) { + grp = NULL; + } else { +#ifdef HAVE_LIBCAPSICUM + if (capgrp != NULL) + grp = cap_getgrgid(capgrp, statp->st_gid); + else +#endif + grp = getgrgid(statp->st_gid); + } + if (grp == NULL) printf("gid=%ju, ", (uintmax_t)statp->st_gid); else printf("gid=\"%s\", ", grp->gr_name); @@ -1786,7 +1866,7 @@ ktrcapfail(struct ktr_cap_fail *ktr) /* operation on fd with insufficient capabilities */ printf("operation requires "); capname(&ktr->cap_needed); - printf(", process holds "); + printf(", descriptor holds "); capname(&ktr->cap_held); break; case CAPFAIL_INCREASE: @@ -1840,8 +1920,11 @@ linux_ktrsyscall(struct ktr_syscall *ktr) if (ktr->ktr_code >= nlinux_syscalls || ktr->ktr_code < 0) printf("[%d]", ktr->ktr_code); - else + else { printf("%s", linux_syscallnames[ktr->ktr_code]); + if (syscallno) + printf("[%d]", ktr->ktr_code); + } ip = &ktr->ktr_args[0]; if (narg) { char c = '('; @@ -1861,8 +1944,12 @@ linux_ktrsysret(struct ktr_sysret *ktr) if (code >= nlinux_syscalls || code < 0) printf("[%d] ", code); - else - printf("%s ", linux_syscallnames[code]); + else { + printf("%s", linux_syscallnames[code]); + if (syscallno) + printf("[%d]", code); + printf(" "); + } if (error == 0) { if (fancy) { @@ -1895,7 +1982,7 @@ linux_ktrsysret(struct ktr_sysret *ktr) void usage(void) { - fprintf(stderr, "usage: kdump [-dEnlHRrsTA] [-f trfile] " + fprintf(stderr, "usage: kdump [-dEnlHRrSsTA] [-f trfile] " "[-m maxdata] [-p pid] [-t trstr]\n"); exit(1); } diff --git a/usr.bin/kdump/mkioctls b/usr.bin/kdump/mkioctls index d6209aa9a8e1..f9dff5087f4b 100644 --- a/usr.bin/kdump/mkioctls +++ b/usr.bin/kdump/mkioctls @@ -21,7 +21,8 @@ LC_ALL=C; export LC_ALL # XXX should we use an ANSI cpp? ioctl_includes=$( cd $includedir - find -H -s * -name '*.h' | grep -v '.*disk.*\.h' | \ + find -H -s * -name '*.h' | \ + egrep -v '(.*disk.*|net/pfvar|net/if_pfsync)\.h' | \ xargs egrep -l \ '^#[ ]*define[ ]+[A-Za-z_][A-Za-z0-9_]*[ ]+_IO[^a-z0-9_]' | awk '{printf("#include <%s>\\n", $1)}' @@ -54,7 +55,10 @@ BEGIN { print "#include <net/ethernet.h>" print "#include <net/if.h>" print "#include <net/if_var.h>" + print "#ifdef PF" print "#include <net/pfvar.h>" + print "#include <net/if_pfsync.h>" + print "#endif" print "#include <net/route.h>" print "#include <netinet/in.h>" print "#include <netinet/ip_mroute.h>" diff --git a/usr.bin/kdump/mksubr b/usr.bin/kdump/mksubr index 1859086af1c8..d8d803fa9256 100644 --- a/usr.bin/kdump/mksubr +++ b/usr.bin/kdump/mksubr @@ -187,7 +187,7 @@ cat <<_EOF_ #include <sys/shm.h> #include <nfsserver/nfs.h> #include <ufs/ufs/quota.h> -#include <sys/capability.h> +#include <sys/capsicum.h> #include <vm/vm.h> #include <vm/vm_param.h> @@ -448,7 +448,7 @@ _EOF_ auto_or_type "accessmodename" "[A-Z]_OK[[:space:]]+0?x?[0-9A-Fa-f]+" "sys/unistd.h" auto_switch_type "acltypename" "ACL_TYPE_[A-Z4_]+[[:space:]]+0x[0-9]+" "sys/acl.h" -auto_or_type "capfcntlname" "CAP_FCNTL_[A-Z]+[[:space:]]+\(1" "sys/capability.h" +auto_or_type "capfcntlname" "CAP_FCNTL_[A-Z]+[[:space:]]+\(1" "sys/capsicum.h" auto_switch_type "extattrctlname" "EXTATTR_NAMESPACE_[A-Z]+[[:space:]]+0x[0-9]+" "sys/extattr.h" auto_switch_type "fadvisebehavname" "POSIX_FADV_[A-Z]+[[:space:]]+[0-9]+" "sys/fcntl.h" auto_or_type "flagsname" "O_[A-Z]+[[:space:]]+0x[0-9A-Fa-f]+" "sys/fcntl.h" @@ -679,7 +679,7 @@ cat <<_EOF_ _EOF_ egrep '#define[[:space:]]+CAP_[A-Z_]+[[:space:]]+CAPRIGHT\([0-9],[[:space:]]+0x[0-9]{16}ULL\)' \ - $include_dir/sys/capability.h | \ + $include_dir/sys/capsicum.h | \ sed -E 's/[ ]+/ /g' | \ awk -F '[ \(,\)]' ' BEGIN { |