aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/avc.c
diff options
context:
space:
mode:
authorStephen Smalley <sds@tycho.nsa.gov>2007-06-07 15:34:10 -0400
committerJames Morris <jmorris@namei.org>2007-07-11 22:52:25 -0400
commit2c3c05dbcbc7b9d71549fe0e2b249f10f5a66518 (patch)
treebab75df9fafc435f3370a6d773d3284716347249 /security/selinux/avc.c
parent9dc9978084ea2a96b9f42752753d9e38a9f9d7b2 (diff)
SELinux: allow preemption between transition permission checks
In security_get_user_sids, move the transition permission checks outside of the section holding the policy rdlock, and use the AVC to perform the checks, calling cond_resched after each one. These changes should allow preemption between the individual checks and enable caching of the results. It may however increase the overall time spent in the function in some cases, particularly in the cache miss case. The long term fix will be to take much of this logic to userspace by exporting additional state via selinuxfs, and ultimately deprecating and eliminating this interface from the kernel. Tested-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov> Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'security/selinux/avc.c')
-rw-r--r--security/selinux/avc.c10
1 files changed, 6 insertions, 4 deletions
diff --git a/security/selinux/avc.c b/security/selinux/avc.c
index e4396a89edc6..cc5fcef9e226 100644
--- a/security/selinux/avc.c
+++ b/security/selinux/avc.c
@@ -832,6 +832,7 @@ int avc_ss_reset(u32 seqno)
832 * @tsid: target security identifier 832 * @tsid: target security identifier
833 * @tclass: target security class 833 * @tclass: target security class
834 * @requested: requested permissions, interpreted based on @tclass 834 * @requested: requested permissions, interpreted based on @tclass
835 * @flags: AVC_STRICT or 0
835 * @avd: access vector decisions 836 * @avd: access vector decisions
836 * 837 *
837 * Check the AVC to determine whether the @requested permissions are granted 838 * Check the AVC to determine whether the @requested permissions are granted
@@ -846,8 +847,9 @@ int avc_ss_reset(u32 seqno)
846 * should be released for the auditing. 847 * should be released for the auditing.
847 */ 848 */
848int avc_has_perm_noaudit(u32 ssid, u32 tsid, 849int avc_has_perm_noaudit(u32 ssid, u32 tsid,
849 u16 tclass, u32 requested, 850 u16 tclass, u32 requested,
850 struct av_decision *avd) 851 unsigned flags,
852 struct av_decision *avd)
851{ 853{
852 struct avc_node *node; 854 struct avc_node *node;
853 struct avc_entry entry, *p_ae; 855 struct avc_entry entry, *p_ae;
@@ -874,7 +876,7 @@ int avc_has_perm_noaudit(u32 ssid, u32 tsid,
874 denied = requested & ~(p_ae->avd.allowed); 876 denied = requested & ~(p_ae->avd.allowed);
875 877
876 if (!requested || denied) { 878 if (!requested || denied) {
877 if (selinux_enforcing) 879 if (selinux_enforcing || (flags & AVC_STRICT))
878 rc = -EACCES; 880 rc = -EACCES;
879 else 881 else
880 if (node) 882 if (node)
@@ -909,7 +911,7 @@ int avc_has_perm(u32 ssid, u32 tsid, u16 tclass,
909 struct av_decision avd; 911 struct av_decision avd;
910 int rc; 912 int rc;
911 913
912 rc = avc_has_perm_noaudit(ssid, tsid, tclass, requested, &avd); 914 rc = avc_has_perm_noaudit(ssid, tsid, tclass, requested, 0, &avd);
913 avc_audit(ssid, tsid, tclass, requested, &avd, rc, auditdata); 915 avc_audit(ssid, tsid, tclass, requested, &avd, rc, auditdata);
914 return rc; 916 return rc;
915} 917}