Author: des
Date: Tue Oct 11 20:37:10 2011
New Revision: 226269
URL: http://svn.freebsd.org/changeset/base/226269

Log:
  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).

Modified:
  head/lib/libc/sys/ktrace.2
  head/sys/kern/kern_ktrace.c
  head/sys/kern/sys_capability.c
  head/sys/sys/ktrace.h
  head/usr.bin/kdump/kdump.c
  head/usr.bin/ktrace/ktrace.1
  head/usr.bin/ktrace/ktrace.h
  head/usr.bin/ktrace/subr.c

Modified: head/lib/libc/sys/ktrace.2
==============================================================================
--- head/lib/libc/sys/ktrace.2  Tue Oct 11 19:31:02 2011        (r226268)
+++ head/lib/libc/sys/ktrace.2  Tue Oct 11 20:37:10 2011        (r226269)
@@ -28,7 +28,7 @@
 .\"     @(#)ktrace.2   8.1 (Berkeley) 6/4/93
 .\" $FreeBSD$
 .\"
-.Dd October 9, 2011
+.Dd October 10, 2011
 .Dt KTRACE 2
 .Os
 .Sh NAME
@@ -67,9 +67,9 @@ The
 argument specifies the requested ktrace operation.
 The defined operations are:
 .Bl -column KTRFLAG_DESCENDXXX -offset indent
-.It "KTROP_SET Enable trace points specified in"
+.It "KTROP_SET         Enable trace points specified in"
 .Fa trpoints .
-.It "KTROP_CLEAR       Disable trace points specified in
+.It "KTROP_CLEAR       Disable trace points specified in"
 .Fa trpoints .
 .It "KTROP_CLEARFILE   Stop all tracing."
 .It "KTRFLAG_DESCEND   The tracing change should apply to the"
@@ -93,6 +93,7 @@ generate much output).
 .It "KTRFAC_SYSCTL     Trace sysctls."
 .It "KTRFAC_PROCCTOR   Trace process construction."
 .It "KTRFAC_PROCDTOR   Trace process destruction."
+.It "KTRFAC_CAPFAIL    Trace capability failures."
 .It "KTRFAC_INHERIT    Inherit tracing to future children."
 .El
 .Pp

Modified: head/sys/kern/kern_ktrace.c
==============================================================================
--- head/sys/kern/kern_ktrace.c Tue Oct 11 19:31:02 2011        (r226268)
+++ head/sys/kern/kern_ktrace.c Tue Oct 11 20:37:10 2011        (r226269)
@@ -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 */

Modified: head/sys/kern/sys_capability.c
==============================================================================
--- head/sys/kern/sys_capability.c      Tue Oct 11 19:31:02 2011        
(r226268)
+++ head/sys/kern/sys_capability.c      Tue Oct 11 20:37:10 2011        
(r226269)
@@ -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);
 }
 

Modified: head/sys/sys/ktrace.h
==============================================================================
--- head/sys/sys/ktrace.h       Tue Oct 11 19:31:02 2011        (r226268)
+++ head/sys/sys/ktrace.h       Tue Oct 11 20:37:10 2011        (r226269)
@@ -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) \

Modified: head/usr.bin/kdump/kdump.c
==============================================================================
--- head/usr.bin/kdump/kdump.c  Tue Oct 11 19:31:02 2011        (r226268)
+++ head/usr.bin/kdump/kdump.c  Tue Oct 11 20:37:10 2011        (r226269)
@@ -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_in
 {
        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_in
                                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)

Modified: head/usr.bin/ktrace/ktrace.1
==============================================================================
--- head/usr.bin/ktrace/ktrace.1        Tue Oct 11 19:31:02 2011        
(r226268)
+++ head/usr.bin/ktrace/ktrace.1        Tue Oct 11 20:37:10 2011        
(r226269)
@@ -28,7 +28,7 @@
 .\"    @(#)ktrace.1    8.1 (Berkeley) 6/6/93
 .\" $FreeBSD$
 .\"
-.Dd February 23, 2008
+.Dd October 10, 2011
 .Dt KTRACE 1
 .Os
 .Sh NAME
@@ -113,6 +113,8 @@ trace
 .Tn I/O
 .It Cm n
 trace namei translations
+.It Cm p
+trace capability check failures
 .It Cm s
 trace signal processing
 .It Cm t
@@ -127,7 +129,7 @@ trace
 requests
 .It Cm +
 trace the default set of trace points -
-.Cm c , i , n , s , t , u , y
+.Cm c , i , n , p , s , t , u , y
 .El
 .It Ar command
 Execute

Modified: head/usr.bin/ktrace/ktrace.h
==============================================================================
--- head/usr.bin/ktrace/ktrace.h        Tue Oct 11 19:31:02 2011        
(r226268)
+++ head/usr.bin/ktrace/ktrace.h        Tue Oct 11 20:37:10 2011        
(r226269)
@@ -32,7 +32,7 @@
 
 #define DEF_POINTS (KTRFAC_SYSCALL | KTRFAC_SYSRET | KTRFAC_NAMEI | \
                    KTRFAC_GENIO | KTRFAC_PSIG | KTRFAC_USER | \
-                   KTRFAC_STRUCT | KTRFAC_SYSCTL)
+                   KTRFAC_STRUCT | KTRFAC_SYSCTL | KTRFAC_CAPFAIL)
 
 #define PROC_ABI_POINTS (KTRFAC_PROCCTOR | KTRFAC_PROCDTOR)
 

Modified: head/usr.bin/ktrace/subr.c
==============================================================================
--- head/usr.bin/ktrace/subr.c  Tue Oct 11 19:31:02 2011        (r226268)
+++ head/usr.bin/ktrace/subr.c  Tue Oct 11 20:37:10 2011        (r226269)
@@ -61,11 +61,14 @@ getpoints(char *s)
                case 'c':
                        facs |= KTRFAC_SYSCALL | KTRFAC_SYSRET;
                        break;
+               case 'i':
+                       facs |= KTRFAC_GENIO;
+                       break;
                case 'n':
                        facs |= KTRFAC_NAMEI;
                        break;
-               case 'i':
-                       facs |= KTRFAC_GENIO;
+               case 'p':
+                       facs |= KTRFAC_CAPFAIL;
                        break;
                case 's':
                        facs |= KTRFAC_PSIG;
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to