aboutsummaryrefslogtreecommitdiff
path: root/usr.bin/kdump
diff options
context:
space:
mode:
authorSimon J. Gerraty <sjg@FreeBSD.org>2014-04-28 07:50:45 +0000
committerSimon J. Gerraty <sjg@FreeBSD.org>2014-04-28 07:50:45 +0000
commit3b8f08459569bf0faa21473e5cec2491e95c9349 (patch)
tree80f45dd81ca716bcd7ca9674581e1fc40b93cd34 /usr.bin/kdump
parent9d2ab4a62d6733c45958627ac113bdbd818d1e2a (diff)
parentb2ba55951383498f252746f618d513139da06e8e (diff)
downloadsrc-3b8f08459569bf0faa21473e5cec2491e95c9349.tar.gz
src-3b8f08459569bf0faa21473e5cec2491e95c9349.zip
Notes
Diffstat (limited to 'usr.bin/kdump')
-rw-r--r--usr.bin/kdump/Makefile12
-rw-r--r--usr.bin/kdump/kdump.16
-rw-r--r--usr.bin/kdump/kdump.c209
-rw-r--r--usr.bin/kdump/mkioctls6
-rw-r--r--usr.bin/kdump/mksubr6
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(&ltime);
}
+#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 {