aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/include/avc.h
diff options
context:
space:
mode:
authorEric Paris <eparis@redhat.com>2012-04-04 15:01:42 -0400
committerEric Paris <eparis@redhat.com>2012-04-09 12:22:59 -0400
commit2e33405785d3eaec303c54b4a10afdebf3729da7 (patch)
treef4c0d114503796e9f958341393e336f76a7eb6dd /security/selinux/include/avc.h
parent154c50ca4eb9ae472f50b6a481213e21ead4457d (diff)
SELinux: delay initialization of audit data in selinux_inode_permission
We pay a rather large overhead initializing the common_audit_data. Since we only need this information if we actually emit an audit message there is little need to set it up in the hot path. This patch splits the functionality of avc_has_perm() into avc_has_perm_noaudit(), avc_audit_required() and slow_avc_audit(). But we take care of setting up to audit between required() and the actual audit call. Thus saving measurable time in a hot path. Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov> Signed-off-by: Eric Paris <eparis@redhat.com>
Diffstat (limited to 'security/selinux/include/avc.h')
-rw-r--r--security/selinux/include/avc.h82
1 files changed, 77 insertions, 5 deletions
diff --git a/security/selinux/include/avc.h b/security/selinux/include/avc.h
index 1931370233d7..e4e50bb218ee 100644
--- a/security/selinux/include/avc.h
+++ b/security/selinux/include/avc.h
@@ -77,11 +77,83 @@ struct selinux_audit_data {
77 77
78void __init avc_init(void); 78void __init avc_init(void);
79 79
80int avc_audit(u32 ssid, u32 tsid, 80static inline u32 avc_audit_required(u32 requested,
81 u16 tclass, u32 requested, 81 struct av_decision *avd,
82 struct av_decision *avd, 82 int result,
83 int result, 83 u32 auditdeny,
84 struct common_audit_data *a, unsigned flags); 84 u32 *deniedp)
85{
86 u32 denied, audited;
87 denied = requested & ~avd->allowed;
88 if (unlikely(denied)) {
89 audited = denied & avd->auditdeny;
90 /*
91 * auditdeny is TRICKY! Setting a bit in
92 * this field means that ANY denials should NOT be audited if
93 * the policy contains an explicit dontaudit rule for that
94 * permission. Take notice that this is unrelated to the
95 * actual permissions that were denied. As an example lets
96 * assume:
97 *
98 * denied == READ
99 * avd.auditdeny & ACCESS == 0 (not set means explicit rule)
100 * auditdeny & ACCESS == 1
101 *
102 * We will NOT audit the denial even though the denied
103 * permission was READ and the auditdeny checks were for
104 * ACCESS
105 */
106 if (auditdeny && !(auditdeny & avd->auditdeny))
107 audited = 0;
108 } else if (result)
109 audited = denied = requested;
110 else
111 audited = requested & avd->auditallow;
112 *deniedp = denied;
113 return audited;
114}
115
116int slow_avc_audit(u32 ssid, u32 tsid, u16 tclass,
117 u32 requested, u32 audited, u32 denied,
118 struct common_audit_data *a,
119 unsigned flags);
120
121/**
122 * avc_audit - Audit the granting or denial of permissions.
123 * @ssid: source security identifier
124 * @tsid: target security identifier
125 * @tclass: target security class
126 * @requested: requested permissions
127 * @avd: access vector decisions
128 * @result: result from avc_has_perm_noaudit
129 * @a: auxiliary audit data
130 * @flags: VFS walk flags
131 *
132 * Audit the granting or denial of permissions in accordance
133 * with the policy. This function is typically called by
134 * avc_has_perm() after a permission check, but can also be
135 * called directly by callers who use avc_has_perm_noaudit()
136 * in order to separate the permission check from the auditing.
137 * For example, this separation is useful when the permission check must
138 * be performed under a lock, to allow the lock to be released
139 * before calling the auditing code.
140 */
141static inline int avc_audit(u32 ssid, u32 tsid,
142 u16 tclass, u32 requested,
143 struct av_decision *avd,
144 int result,
145 struct common_audit_data *a, unsigned flags)
146{
147 u32 audited, denied;
148 audited = avc_audit_required(requested, avd, result,
149 a ? a->selinux_audit_data->auditdeny : 0,
150 &denied);
151 if (likely(!audited))
152 return 0;
153 return slow_avc_audit(ssid, tsid, tclass,
154 requested, audited, denied,
155 a, flags);
156}
85 157
86#define AVC_STRICT 1 /* Ignore permissive mode. */ 158#define AVC_STRICT 1 /* Ignore permissive mode. */
87int avc_has_perm_noaudit(u32 ssid, u32 tsid, 159int avc_has_perm_noaudit(u32 ssid, u32 tsid,