summaryrefslogtreecommitdiffstats
path: root/usr.bin/kdump
diff options
context:
space:
mode:
authordes <des@FreeBSD.org>2011-10-11 20:37:10 +0000
committerdes <des@FreeBSD.org>2011-10-11 20:37:10 +0000
commit9b8d9b3ed18d6b0c6f881baf309e3935335bc7b1 (patch)
treee9843d4ebf0bc386f58afa84935ecf276f03447c /usr.bin/kdump
parent42aa10a9a139809533ee7832f9cdecc8bead877d (diff)
downloadFreeBSD-src-9b8d9b3ed18d6b0c6f881baf309e3935335bc7b1.zip
FreeBSD-src-9b8d9b3ed18d6b0c6f881baf309e3935335bc7b1.tar.gz
Add a new trace point, KTRFAC_CAPFAIL, which traces capability check
failures. It is included in the default set for ktrace(1) and kdump(1).
Diffstat (limited to 'usr.bin/kdump')
-rw-r--r--usr.bin/kdump/kdump.c49
1 files changed, 43 insertions, 6 deletions
diff --git a/usr.bin/kdump/kdump.c b/usr.bin/kdump/kdump.c
index 7e1c08d..8f2f4db 100644
--- a/usr.bin/kdump/kdump.c
+++ b/usr.bin/kdump/kdump.c
@@ -99,6 +99,7 @@ void ktruser(int, unsigned char *);
void ktrsockaddr(struct sockaddr *);
void ktrstat(struct stat *);
void ktrstruct(char *, size_t);
+void ktrcapfail(struct ktr_cap_fail *);
void usage(void);
void ioctlname(unsigned long, int);
@@ -301,6 +302,8 @@ main(int argc, char *argv[])
case KTR_STRUCT:
ktrstruct(m, ktrlen);
break;
+ case KTR_CAPFAIL:
+ ktrcapfail((struct ktr_cap_fail *)m);
default:
printf("\n");
break;
@@ -440,6 +443,9 @@ dumpheader(struct ktr_header *kth)
/* FALLTHROUGH */
case KTR_PROCDTOR:
return;
+ case KTR_CAPFAIL:
+ type = "CAP ";
+ break;
default:
sprintf(unknown, "UNKNOWN(%d)", kth->ktr_type);
type = unknown;
@@ -488,6 +494,7 @@ ktrsyscall(struct ktr_syscall *ktr, u_int flags)
{
int narg = ktr->ktr_narg;
register_t *ip;
+ intmax_t arg;
if ((flags != 0 && ((flags & SV_ABI_MASK) != SV_ABI_FREEBSD)) ||
(ktr->ktr_code >= nsyscalls || ktr->ktr_code < 0))
@@ -978,12 +985,33 @@ ktrsyscall(struct ktr_syscall *ktr, u_int flags)
ip++;
narg--;
break;
- case SYS_cap_new:
- print_number(ip, narg, c);
- putchar(',');
- capname(*ip);
- ip++;
- narg--;
+ case SYS_cap_new:
+ print_number(ip, narg, c);
+ putchar(',');
+ arg = *ip;
+ ip++;
+ narg--;
+ /*
+ * Hack: the second argument is a
+ * cap_rights_t, which 64 bits wide, so on
+ * 32-bit systems, it is split between two
+ * registers.
+ *
+ * Since sizeof() is not evaluated by the
+ * preprocessor, we can't use an #ifdef,
+ * but the compiler will probably optimize
+ * the code out anyway.
+ */
+ if (sizeof(cap_rights_t) > sizeof(register_t)) {
+#if _BYTE_ORDER == _LITTLE_ENDIAN
+ arg = ((intmax_t)*ip << 32) + arg;
+#else
+ arg = (arg << 32) + *ip;
+#endif
+ ip++;
+ narg--;
+ }
+ capname(arg);
break;
}
}
@@ -1554,6 +1582,15 @@ invalid:
printf("invalid record\n");
}
+void
+ktrcapfail(struct ktr_cap_fail *ktr)
+{
+ printf("needed ");
+ capname((intmax_t)ktr->cap_needed);
+ printf(" held ");
+ capname((intmax_t)ktr->cap_held);
+}
+
#if defined(__amd64__) || defined(__i386__)
void
linux_ktrsyscall(struct ktr_syscall *ktr)
OpenPOWER on IntegriCloud