[PATCH v3 3/3] selinux: add permission names to trace event

From: Thiébaud Weksteen
Date: Mon Aug 17 2020 - 13:24:48 EST


From: Peter Enderborg <peter.enderborg@xxxxxxxx>

In the print out add permissions, it will look like:
<...>-1042 [007] .... 201.965142: selinux_audited:
requested=0x4000000 denied=0x4000000 audited=0x4000000
result=-13
scontext=system_u:system_r:cupsd_t:s0-s0:c0.c1023
tcontext=system_u:object_r:bin_t:s0
tclass=file permissions={ !entrypoint }

This patch is adding the "permissions={ !entrypoint }".
The permissions preceded by "!" have been denied and the permissions
without have been accepted.

Note that permission filtering is done on the audited, denied or
requested attributes.

Suggested-by: Steven Rostedt <rostedt@xxxxxxxxxxx>
Suggested-by: Stephen Smalley <stephen.smalley.work@xxxxxxxxx>
Reviewed-by: Thiébaud Weksteen <tweek@xxxxxxxxxx>
Signed-off-by: Peter Enderborg <peter.enderborg@xxxxxxxx>
---
include/trace/events/avc.h | 11 +++++++++--
security/selinux/avc.c | 36 ++++++++++++++++++++++++++++++++++++
2 files changed, 45 insertions(+), 2 deletions(-)

diff --git a/include/trace/events/avc.h b/include/trace/events/avc.h
index b55fda2e0773..94bca8bef8d2 100644
--- a/include/trace/events/avc.h
+++ b/include/trace/events/avc.h
@@ -10,6 +10,10 @@
#define _TRACE_SELINUX_H

#include <linux/tracepoint.h>
+#include <linux/trace_seq.h>
+
+extern const char *avc_trace_perm_to_name(struct trace_seq *p, u16 class, u32 audited, u32 denied);
+#define __perm_to_name(class, audited, denied) avc_trace_perm_to_name(p, class, audited, denied)

TRACE_EVENT(selinux_audited,

@@ -29,6 +33,7 @@ TRACE_EVENT(selinux_audited,
__string(scontext, scontext)
__string(tcontext, tcontext)
__string(tclass, tclass)
+ __field(u16, utclass)
),

TP_fast_assign(
@@ -36,14 +41,16 @@ TRACE_EVENT(selinux_audited,
__entry->denied = sad->denied;
__entry->audited = sad->audited;
__entry->result = sad->result;
+ __entry->utclass = sad->tclass;
__assign_str(tcontext, tcontext);
__assign_str(scontext, scontext);
__assign_str(tclass, tclass);
),

- TP_printk("requested=0x%x denied=0x%x audited=0x%x result=%d scontext=%s tcontext=%s tclass=%s",
+ TP_printk("requested=0x%x denied=0x%x audited=0x%x result=%d scontext=%s tcontext=%s tclass=%s permissions={%s }",
__entry->requested, __entry->denied, __entry->audited, __entry->result,
- __get_str(scontext), __get_str(tcontext), __get_str(tclass)
+ __get_str(scontext), __get_str(tcontext), __get_str(tclass),
+ __perm_to_name(__entry->utclass, __entry->audited, __entry->denied)
)
);

diff --git a/security/selinux/avc.c b/security/selinux/avc.c
index 7de5cc5169af..d585b68c2a50 100644
--- a/security/selinux/avc.c
+++ b/security/selinux/avc.c
@@ -695,6 +695,7 @@ static void avc_audit_pre_callback(struct audit_buffer *ab, void *a)
audit_log_format(ab, " } for ");
}

+
/**
* avc_audit_post_callback - SELinux specific information
* will be called by generic audit code
@@ -991,6 +992,41 @@ int avc_ss_reset(struct selinux_avc *avc, u32 seqno)
return rc;
}

+/**
+ * avc_trace_perm_to_name - SELinux help function for trace
+ * @p pointer to output storage
+ * @tclass tclass for the event
+ * @av access vector
+ * @avdenied denied permissions in av format
+ */
+const char *avc_trace_perm_to_name(struct trace_seq *p, u16 tclass, u32 av, u32 avdenied)
+{
+ const char *ret = trace_seq_buffer_ptr(p);
+ int i, perm;
+ const char **perms;
+
+ if (WARN_ON(!tclass || tclass >= ARRAY_SIZE(secclass_map)))
+ return NULL;
+
+ perms = secclass_map[tclass-1].perms;
+
+ i = 0;
+ perm = 1;
+ while (i < (sizeof(av) * 8)) {
+ if ((perm & av) && perms[i]) {
+ if (!(perm & avdenied))
+ trace_seq_printf(p, " %s", perms[i]);
+ else
+ trace_seq_printf(p, " !%s", perms[i]);
+ av &= ~perm;
+ }
+ i++;
+ perm <<= 1;
+ }
+
+ return ret;
+}
+
/*
* Slow-path helper function for avc_has_perm_noaudit,
* when the avc_node lookup fails. We get called with
--
2.28.0.220.ged08abb693-goog