diff --git a/drivers/android/vendor_hooks.c b/drivers/android/vendor_hooks.c index 680a925a48e9..1441a69df3f2 100644 --- a/drivers/android/vendor_hooks.c +++ b/drivers/android/vendor_hooks.c @@ -41,6 +41,7 @@ #include #include #include +#include /* * Export tracepoints that act as a bare tracehook (ie: have no trace event @@ -183,3 +184,7 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_rwsem_wake_finish); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_do_undefinstr); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_bad_mode); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_arm64_serror_panic); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_selinux_avc_insert); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_selinux_avc_node_delete); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_selinux_avc_node_replace); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_selinux_avc_lookup); diff --git a/include/trace/hooks/avc.h b/include/trace/hooks/avc.h new file mode 100644 index 000000000000..2c76e02fc3c5 --- /dev/null +++ b/include/trace/hooks/avc.h @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM avc + +#define TRACE_INCLUDE_PATH trace/hooks +#if !defined(_TRACE_HOOK_AVC_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_HOOK_AVC_H +#include +#include +/* + * Following tracepoints are not exported in tracefs and provide a + * mechanism for vendor modules to hook and extend functionality + */ +struct avc_node; +DECLARE_HOOK(android_vh_selinux_avc_insert, + TP_PROTO(const struct avc_node *node), + TP_ARGS(node)); + +DECLARE_HOOK(android_vh_selinux_avc_node_delete, + TP_PROTO(const struct avc_node *node), + TP_ARGS(node)); + +DECLARE_HOOK(android_vh_selinux_avc_node_replace, + TP_PROTO(const struct avc_node *old, const struct avc_node *new), + TP_ARGS(old, new)); + +DECLARE_HOOK(android_vh_selinux_avc_lookup, + TP_PROTO(const struct avc_node *node, u32 ssid, u32 tsid, u16 tclass), + TP_ARGS(node, ssid, tsid, tclass)); + +#endif /* _TRACE_HOOK_AVC_H */ +/* This part must be outside protection */ +#include diff --git a/security/selinux/avc.c b/security/selinux/avc.c index 3c05827608b6..a6719fd24d20 100644 --- a/security/selinux/avc.c +++ b/security/selinux/avc.c @@ -44,6 +44,9 @@ #define avc_cache_stats_incr(field) do {} while (0) #endif +#undef CREATE_TRACE_POINTS +#include + struct avc_entry { u32 ssid; u32 tsid; @@ -440,6 +443,7 @@ static void avc_node_free(struct rcu_head *rhead) static void avc_node_delete(struct selinux_avc *avc, struct avc_node *node) { + trace_android_vh_selinux_avc_node_delete(node); hlist_del_rcu(&node->list); call_rcu(&node->rhead, avc_node_free); atomic_dec(&avc->avc_cache.active_nodes); @@ -456,6 +460,7 @@ static void avc_node_kill(struct selinux_avc *avc, struct avc_node *node) static void avc_node_replace(struct selinux_avc *avc, struct avc_node *new, struct avc_node *old) { + trace_android_vh_selinux_avc_node_replace(old, new); hlist_replace_rcu(&old->list, &new->list); call_rcu(&old->rhead, avc_node_free); atomic_dec(&avc->avc_cache.active_nodes); @@ -564,8 +569,10 @@ static struct avc_node *avc_lookup(struct selinux_avc *avc, avc_cache_stats_incr(lookups); node = avc_search_node(avc, ssid, tsid, tclass); - if (node) + if (node) { + trace_android_vh_selinux_avc_lookup(node, ssid, tsid, tclass); return node; + } avc_cache_stats_incr(misses); return NULL; @@ -649,6 +656,7 @@ static struct avc_node *avc_insert(struct selinux_avc *avc, } } hlist_add_head_rcu(&node->list, head); + trace_android_vh_selinux_avc_insert(node); found: spin_unlock_irqrestore(lock, flag); return node;