From 6605f296d3075b0830251ae3f04fb88591e1e863 Mon Sep 17 00:00:00 2001 From: Kuan-Ying Lee Date: Tue, 5 Oct 2021 17:07:57 +0800 Subject: [PATCH] ANDROID: security: selinux: Add restricted vendor hook in avc Add restricted vendor hook for avc, so we can get avc_node information to monitor avc lifetime. Bug: 181639260 Signed-off-by: Kuan-Ying Lee Change-Id: Idbebeca926c2cb407264f2872b032e1f18462697 --- drivers/android/vendor_hooks.c | 5 +++++ include/trace/hooks/avc.h | 33 +++++++++++++++++++++++++++++++++ security/selinux/avc.c | 10 +++++++++- 3 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 include/trace/hooks/avc.h diff --git a/drivers/android/vendor_hooks.c b/drivers/android/vendor_hooks.c index 4ba6f1b811a9..85f16eaeffa7 100644 --- a/drivers/android/vendor_hooks.c +++ b/drivers/android/vendor_hooks.c @@ -37,6 +37,7 @@ #include #include #include +#include /* * Export tracepoints that act as a bare tracehook (ie: have no trace event @@ -174,3 +175,7 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_dequeue_entity); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_entity_tick); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_enqueue_task_fair); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_dequeue_task_fair); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_selinux_avc_insert); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_selinux_avc_node_delete); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_selinux_avc_node_replace); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_selinux_avc_lookup); diff --git a/include/trace/hooks/avc.h b/include/trace/hooks/avc.h new file mode 100644 index 000000000000..1ac5fa3cc08f --- /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_RESTRICTED_HOOK(android_rvh_selinux_avc_insert, + TP_PROTO(const struct avc_node *node), + TP_ARGS(node), 1); + +DECLARE_RESTRICTED_HOOK(android_rvh_selinux_avc_node_delete, + TP_PROTO(const struct avc_node *node), + TP_ARGS(node), 1); + +DECLARE_RESTRICTED_HOOK(android_rvh_selinux_avc_node_replace, + TP_PROTO(const struct avc_node *old, const struct avc_node *new), + TP_ARGS(old, new), 1); + +DECLARE_RESTRICTED_HOOK(android_rvh_selinux_avc_lookup, + TP_PROTO(const struct avc_node *node, u32 ssid, u32 tsid, u16 tclass), + TP_ARGS(node, ssid, tsid, tclass), 1); + +#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 97f4c944a20f..e0582fed1279 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; @@ -441,6 +444,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_rvh_selinux_avc_node_delete(node); hlist_del_rcu(&node->list); call_rcu(&node->rhead, avc_node_free); atomic_dec(&avc->avc_cache.active_nodes); @@ -457,6 +461,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_rvh_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); @@ -565,8 +570,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_rvh_selinux_avc_lookup(node, ssid, tsid, tclass); return node; + } avc_cache_stats_incr(misses); return NULL; @@ -650,6 +657,7 @@ static struct avc_node *avc_insert(struct selinux_avc *avc, } } hlist_add_head_rcu(&node->list, head); + trace_android_rvh_selinux_avc_insert(node); found: spin_unlock_irqrestore(lock, flag); return node;