Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F115661306
D40676.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
7 KB
Referenced Files
None
Subscribers
None
D40676.diff
View Options
diff --git a/sys/kern/kern_ktrace.c b/sys/kern/kern_ktrace.c
--- a/sys/kern/kern_ktrace.c
+++ b/sys/kern/kern_ktrace.c
@@ -923,14 +923,17 @@
}
void
-ktrcapfail(enum ktr_cap_fail_type type, const cap_rights_t *needed,
- const cap_rights_t *held)
+ktrcapfail(enum ktr_cap_violation type, const void *data)
{
struct thread *td = curthread;
struct ktr_request *req;
struct ktr_cap_fail *kcf;
+ union ktr_cap_data *kcd;
- if (__predict_false(curthread->td_pflags & TDP_INKTRACE))
+ if (__predict_false(td->td_pflags & TDP_INKTRACE))
+ return;
+ if (type != CAPFAIL_SYSCALL &&
+ (td->td_sa.callp->sy_flags & SYF_CAPENABLED) == 0)
return;
req = ktr_getrequest(KTR_CAPFAIL);
@@ -938,14 +941,32 @@
return;
kcf = &req->ktr_data.ktr_cap_fail;
kcf->cap_type = type;
- if (needed != NULL)
- kcf->cap_needed = *needed;
- else
- cap_rights_init(&kcf->cap_needed);
- if (held != NULL)
- kcf->cap_held = *held;
- else
- cap_rights_init(&kcf->cap_held);
+ kcf->cap_code = td->td_sa.code;
+ kcf->cap_svflags = td->td_proc->p_sysent->sv_flags;
+ if (data != NULL) {
+ kcd = &kcf->cap_data;
+ switch (type) {
+ case CAPFAIL_NOTCAPABLE:
+ case CAPFAIL_INCREASE:
+ kcd->cap_needed = *(const cap_rights_t *)data;
+ kcd->cap_held = *((const cap_rights_t *)data + 1);
+ break;
+ case CAPFAIL_SYSCALL:
+ case CAPFAIL_SIGNAL:
+ case CAPFAIL_PROTO:
+ kcd->cap_int = *(const int *)data;
+ break;
+ case CAPFAIL_SOCKADDR:
+ kcd->cap_sockaddr = *(const struct sockaddr *)data;
+ break;
+ case CAPFAIL_NAMEI:
+ strlcpy(kcd->cap_path, data, MAXPATHLEN);
+ break;
+ case CAPFAIL_CPUSET:
+ default:
+ break;
+ }
+ }
ktr_enqueuerequest(td, req);
ktrace_exit(td);
}
diff --git a/sys/kern/sys_capability.c b/sys/kern/sys_capability.c
--- a/sys/kern/sys_capability.c
+++ b/sys/kern/sys_capability.c
@@ -154,14 +154,13 @@
static inline int
_cap_check(const cap_rights_t *havep, const cap_rights_t *needp,
- enum ktr_cap_fail_type type)
+ enum ktr_cap_violation type)
{
+ const cap_rights_t rights[] = { *needp, *havep };
if (!cap_rights_contains(havep, needp)) {
-#ifdef KTRACE
- if (KTRPOINT(curthread, KTR_CAPFAIL))
- ktrcapfail(type, needp, havep);
-#endif
+ if (CAP_TRACING(curthread))
+ ktrcapfail(type, rights);
return (ENOTCAPABLE);
}
return (0);
@@ -180,11 +179,10 @@
int
cap_check_failed_notcapable(const cap_rights_t *havep, const cap_rights_t *needp)
{
+ const cap_rights_t rights[] = { *needp, *havep };
-#ifdef KTRACE
- if (KTRPOINT(curthread, KTR_CAPFAIL))
- ktrcapfail(CAPFAIL_NOTCAPABLE, needp, havep);
-#endif
+ if (CAP_TRACING(curthread))
+ ktrcapfail(CAPFAIL_NOTCAPABLE, rights);
return (ENOTCAPABLE);
}
diff --git a/sys/sys/capsicum.h b/sys/sys/capsicum.h
--- a/sys/sys/capsicum.h
+++ b/sys/sys/capsicum.h
@@ -44,6 +44,7 @@
#include <sys/caprights.h>
#include <sys/file.h>
#include <sys/fcntl.h>
+#include <sys/ktrace.h>
#ifndef _KERNEL
#include <stdbool.h>
@@ -419,6 +420,12 @@
#include <sys/systm.h>
+#ifdef KTRACE
+#define CAP_TRACING(td) KTRPOINT((td), KTR_CAPFAIL)
+#else
+#define CAP_TRACING(td) 0
+#endif
+
#define IN_CAPABILITY_MODE(td) (((td)->td_ucred->cr_flags & CRED_FLAG_CAPMODE) != 0)
struct filedesc;
diff --git a/sys/sys/ktrace.h b/sys/sys/ktrace.h
--- a/sys/sys/ktrace.h
+++ b/sys/sys/ktrace.h
@@ -32,8 +32,10 @@
#ifndef _SYS_KTRACE_H_
#define _SYS_KTRACE_H_
+#include <sys/param.h>
#include <sys/caprights.h>
#include <sys/signal.h>
+#include <sys/socket.h>
#include <sys/_uio.h>
/*
@@ -205,16 +207,31 @@
* KTR_CAPFAIL - trace capability check failures
*/
#define KTR_CAPFAIL 12
-enum ktr_cap_fail_type {
+enum ktr_cap_violation {
CAPFAIL_NOTCAPABLE, /* insufficient capabilities in cap_check() */
- CAPFAIL_INCREASE, /* attempt to increase capabilities */
+ CAPFAIL_INCREASE, /* attempt to increase rights on a capability */
CAPFAIL_SYSCALL, /* disallowed system call */
- CAPFAIL_LOOKUP, /* disallowed VFS lookup */
+ CAPFAIL_SIGNAL, /* sent signal to process other than self */
+ CAPFAIL_PROTO, /* disallowed protocol */
+ CAPFAIL_SOCKADDR, /* restricted address lookup */
+ CAPFAIL_NAMEI, /* restricted namei lookup */
+ CAPFAIL_CPUSET, /* restricted CPU set modification */
};
+
+union ktr_cap_data {
+ cap_rights_t cap_rights[2];
+#define cap_needed cap_rights[0]
+#define cap_held cap_rights[1]
+ int cap_int;
+ struct sockaddr cap_sockaddr;
+ char cap_path[MAXPATHLEN];
+};
+
struct ktr_cap_fail {
- enum ktr_cap_fail_type cap_type;
- cap_rights_t cap_needed;
- cap_rights_t cap_held;
+ enum ktr_cap_violation cap_type;
+ short cap_code;
+ u_int cap_svflags;
+ union ktr_cap_data cap_data;
};
/*
@@ -317,8 +334,7 @@
void ktrstruct(const char *, const void *, size_t);
void ktrstruct_error(const char *, const void *, size_t, int);
void ktrstructarray(const char *, enum uio_seg, const void *, int, size_t);
-void ktrcapfail(enum ktr_cap_fail_type, const cap_rights_t *,
- const cap_rights_t *);
+void ktrcapfail(enum ktr_cap_violation, const void *);
#define ktrcaprights(s) \
ktrstruct("caprights", (s), sizeof(cap_rights_t))
#define ktritimerval(s) \
diff --git a/usr.bin/kdump/kdump.c b/usr.bin/kdump/kdump.c
--- a/usr.bin/kdump/kdump.c
+++ b/usr.bin/kdump/kdump.c
@@ -2125,35 +2125,74 @@
void
ktrcapfail(struct ktr_cap_fail *ktr)
{
+ union ktr_cap_data *kcd = &ktr->cap_data;
+
switch (ktr->cap_type) {
case CAPFAIL_NOTCAPABLE:
/* operation on fd with insufficient capabilities */
printf("operation requires ");
- sysdecode_cap_rights(stdout, &ktr->cap_needed);
+ sysdecode_cap_rights(stdout, &kcd->cap_needed);
printf(", descriptor holds ");
- sysdecode_cap_rights(stdout, &ktr->cap_held);
+ sysdecode_cap_rights(stdout, &kcd->cap_held);
break;
case CAPFAIL_INCREASE:
/* requested more capabilities than fd already has */
printf("attempt to increase capabilities from ");
- sysdecode_cap_rights(stdout, &ktr->cap_held);
+ sysdecode_cap_rights(stdout, &kcd->cap_held);
printf(" to ");
- sysdecode_cap_rights(stdout, &ktr->cap_needed);
+ sysdecode_cap_rights(stdout, &kcd->cap_needed);
break;
case CAPFAIL_SYSCALL:
/* called restricted syscall */
- printf("disallowed system call");
+ printf("system call not allowed: ");
+ syscallname(ktr->cap_code, ktr->cap_svflags);
+ if (syscallabi(ktr->cap_svflags) == SYSDECODE_ABI_FREEBSD) {
+ switch (ktr->cap_code) {
+ case SYS_sysarch:
+ printf(", op: ");
+ print_integer_arg(sysdecode_sysarch_number,
+ kcd->cap_int);
+ break;
+ case SYS_fcntl:
+ printf(", cmd: ");
+ print_integer_arg(sysdecode_fcntl_cmd,
+ kcd->cap_int);
+ break;
+ }
+ }
break;
- case CAPFAIL_LOOKUP:
- /* absolute or AT_FDCWD path, ".." path, etc. */
- printf("restricted VFS lookup");
+ case CAPFAIL_SIGNAL:
+ /* sent signal to proc other than self */
+ syscallname(ktr->cap_code, ktr->cap_svflags);
+ printf(": signal delivery not allowed: ");
+ print_integer_arg(sysdecode_signal, kcd->cap_int);
break;
- default:
- printf("unknown capability failure: ");
- sysdecode_cap_rights(stdout, &ktr->cap_needed);
- printf(" ");
- sysdecode_cap_rights(stdout, &ktr->cap_held);
+ case CAPFAIL_PROTO:
+ /* created socket with restricted protocol */
+ syscallname(ktr->cap_code, ktr->cap_svflags);
+ printf(": protocol not allowed: ");
+ print_integer_arg(sysdecode_ipproto, kcd->cap_int);
break;
+ case CAPFAIL_SOCKADDR:
+ /* unable to look up address */
+ syscallname(ktr->cap_code, ktr->cap_svflags);
+ printf(": restricted address lookup: ");
+ ktrsockaddr(&kcd->cap_sockaddr);
+ return;
+ case CAPFAIL_NAMEI:
+ /* absolute or AT_FDCWD path, ".." path, etc. */
+ syscallname(ktr->cap_code, ktr->cap_svflags);
+ printf(": restricted VFS lookup: %s\n", kcd->cap_path);
+ return;
+ case CAPFAIL_CPUSET:
+ /* modification of an external cpuset */
+ syscallname(ktr->cap_code, ktr->cap_svflags);
+ printf(": restricted cpuset operation\n");
+ return;
+ default:
+ syscallname(ktr->cap_code, ktr->cap_svflags);
+ printf(": unknown capability failure\n");
+ return;
}
printf("\n");
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Apr 27, 5:55 PM (16 h, 45 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
17820489
Default Alt Text
D40676.diff (7 KB)
Attached To
Mode
D40676: ktrace: Record detailed ECAPMODE violations
Attached
Detach File
Event Timeline
Log In to Comment