Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 11 Oct 2011 20:37:10 +0000 (UTC)
From:      Dag-Erling Smorgrav <des@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r226269 - in head: lib/libc/sys sys/kern sys/sys usr.bin/kdump usr.bin/ktrace
Message-ID:  <201110112037.p9BKbA09031459@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201110112037.p9BKbA09031459>