diff options
author | des <des@FreeBSD.org> | 2011-10-11 20:37:10 +0000 |
---|---|---|
committer | des <des@FreeBSD.org> | 2011-10-11 20:37:10 +0000 |
commit | 9b8d9b3ed18d6b0c6f881baf309e3935335bc7b1 (patch) | |
tree | e9843d4ebf0bc386f58afa84935ecf276f03447c /sys | |
parent | 42aa10a9a139809533ee7832f9cdecc8bead877d (diff) | |
download | FreeBSD-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 'sys')
-rw-r--r-- | sys/kern/kern_ktrace.c | 21 | ||||
-rw-r--r-- | sys/kern/sys_capability.c | 10 | ||||
-rw-r--r-- | sys/sys/ktrace.h | 11 |
3 files changed, 41 insertions, 1 deletions
diff --git a/sys/kern/kern_ktrace.c b/sys/kern/kern_ktrace.c index 0f1ad91..bf99971 100644 --- a/sys/kern/kern_ktrace.c +++ b/sys/kern/kern_ktrace.c @@ -95,6 +95,7 @@ struct ktr_request { void *ktr_buffer; union { struct ktr_proc_ctor ktr_proc_ctor; + struct ktr_cap_fail ktr_cap_fail; struct ktr_syscall ktr_syscall; struct ktr_sysret ktr_sysret; struct ktr_genio ktr_genio; @@ -117,6 +118,7 @@ static int data_lengths[] = { 0, /* KTR_SYSCTL */ sizeof(struct ktr_proc_ctor), /* KTR_PROCCTOR */ 0, /* KTR_PROCDTOR */ + sizeof(struct ktr_cap_fail), /* KTR_CAPFAIL */ }; static STAILQ_HEAD(, ktr_request) ktr_free; @@ -768,6 +770,25 @@ ktrstruct(name, data, datalen) req->ktr_header.ktr_len = buflen; ktr_submitrequest(curthread, req); } + +void +ktrcapfail(needed, held) + cap_rights_t needed; + cap_rights_t held; +{ + struct thread *td = curthread; + struct ktr_request *req; + struct ktr_cap_fail *kcf; + + req = ktr_getrequest(KTR_CAPFAIL); + if (req == NULL) + return; + kcf = &req->ktr_data.ktr_cap_fail; + kcf->cap_needed = needed; + kcf->cap_held = held; + ktr_enqueuerequest(td, req); + ktrace_exit(td); +} #endif /* KTRACE */ /* Interface and common routines */ diff --git a/sys/kern/sys_capability.c b/sys/kern/sys_capability.c index 2318b12..b22cfb2 100644 --- a/sys/kern/sys_capability.c +++ b/sys/kern/sys_capability.c @@ -52,6 +52,7 @@ */ #include "opt_capsicum.h" +#include "opt_ktrace.h" #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); @@ -68,6 +69,8 @@ __FBSDID("$FreeBSD$"); #include <sys/sysctl.h> #include <sys/systm.h> #include <sys/ucred.h> +#include <sys/uio.h> +#include <sys/ktrace.h> #include <security/audit/audit.h> @@ -212,8 +215,13 @@ static int cap_check(struct capability *c, cap_rights_t rights) { - if ((c->cap_rights | rights) != c->cap_rights) + if ((c->cap_rights | rights) != c->cap_rights) { +#ifdef KTRACE + if (KTRPOINT(curthread, KTR_CAPFAIL)) + ktrcapfail(rights, c->cap_rights); +#endif return (ENOTCAPABLE); + } return (0); } diff --git a/sys/sys/ktrace.h b/sys/sys/ktrace.h index edd5c02..592db6f 100644 --- a/sys/sys/ktrace.h +++ b/sys/sys/ktrace.h @@ -178,6 +178,15 @@ struct ktr_proc_ctor { #define KTR_PROCDTOR 11 /* + * KTR_CAPFAIL - trace capability check failures + */ +#define KTR_CAPFAIL 12 +struct ktr_cap_fail { + cap_rights_t cap_needed; + cap_rights_t cap_held; +}; + +/* * KTR_DROP - If this bit is set in ktr_type, then at least one event * between the previous record and this record was dropped. */ @@ -198,6 +207,7 @@ struct ktr_proc_ctor { #define KTRFAC_SYSCTL (1<<KTR_SYSCTL) #define KTRFAC_PROCCTOR (1<<KTR_PROCCTOR) #define KTRFAC_PROCDTOR (1<<KTR_PROCDTOR) +#define KTRFAC_CAPFAIL (1<<KTR_CAPFAIL) /* * trace flags (also in p_traceflags) @@ -220,6 +230,7 @@ void ktrprocexit(struct thread *); void ktrprocfork(struct proc *, struct proc *); void ktruserret(struct thread *); void ktrstruct(const char *, void *, size_t); +void ktrcapfail(cap_rights_t, cap_rights_t); #define ktrsockaddr(s) \ ktrstruct("sockaddr", (s), ((struct sockaddr *)(s))->sa_len) #define ktrstat(s) \ |