Smack: Improve access check performance
[kernel/linux-3.0.git] / security / smack / smack_access.c
index 425a6a2..01fd6fd 100644 (file)
@@ -93,7 +93,7 @@ int smk_access_entry(char *subject_label, char *object_label,
 
        list_for_each_entry_rcu(srp, rule_list, list) {
                if (srp->smk_object == object_label &&
-                   srp->smk_subject == subject_label) {
+                   srp->smk_subject->smk_known == subject_label) {
                        may = srp->smk_access;
                        break;
                }
@@ -104,7 +104,7 @@ int smk_access_entry(char *subject_label, char *object_label,
 
 /**
  * smk_access - determine if a subject has a specific access to an object
- * @subject_label: a pointer to the subject's Smack label
+ * @subject_known: a pointer to the subject's Smack label entry
  * @object_label: a pointer to the object's Smack label
  * @request: the access requested, in "MAY" format
  * @a : a pointer to the audit data
@@ -115,10 +115,9 @@ int smk_access_entry(char *subject_label, char *object_label,
  *
  * Smack labels are shared on smack_list
  */
-int smk_access(char *subject_label, char *object_label, int request,
-              struct smk_audit_info *a)
+int smk_access(struct smack_known *subject_known, char *object_label,
+               int request, struct smk_audit_info *a)
 {
-       struct smack_known *skp;
        int may = MAY_NOT;
        int rc = 0;
 
@@ -127,7 +126,7 @@ int smk_access(char *subject_label, char *object_label, int request,
         *
         * A star subject can't access any object.
         */
-       if (subject_label == smack_known_star.smk_known) {
+       if (subject_known == &smack_known_star) {
                rc = -EACCES;
                goto out_audit;
        }
@@ -137,7 +136,7 @@ int smk_access(char *subject_label, char *object_label, int request,
         * An internet subject can access any object.
         */
        if (object_label == smack_known_web.smk_known ||
-           subject_label == smack_known_web.smk_known)
+           subject_known == &smack_known_web)
                goto out_audit;
        /*
         * A star object can be accessed by any subject.
@@ -148,7 +147,7 @@ int smk_access(char *subject_label, char *object_label, int request,
         * An object can be accessed in any way by a subject
         * with the same label.
         */
-       if (subject_label == object_label)
+       if (subject_known->smk_known == object_label)
                goto out_audit;
        /*
         * A hat subject can read any object.
@@ -157,7 +156,7 @@ int smk_access(char *subject_label, char *object_label, int request,
        if ((request & MAY_ANYREAD) == request) {
                if (object_label == smack_known_floor.smk_known)
                        goto out_audit;
-               if (subject_label == smack_known_hat.smk_known)
+               if (subject_known == &smack_known_hat)
                        goto out_audit;
        }
        /*
@@ -167,9 +166,9 @@ int smk_access(char *subject_label, char *object_label, int request,
         * good. A negative response from smk_access_entry()
         * indicates there is no entry for this pair.
         */
-       skp = smk_find_entry(subject_label);
        rcu_read_lock();
-       may = smk_access_entry(subject_label, object_label, &skp->smk_rules);
+       may = smk_access_entry(subject_known->smk_known, object_label,
+                               &subject_known->smk_rules);
        rcu_read_unlock();
 
        if (may > 0 && (request & may) == request)
@@ -179,7 +178,8 @@ int smk_access(char *subject_label, char *object_label, int request,
 out_audit:
 #ifdef CONFIG_AUDIT
        if (a)
-               smack_log(subject_label, object_label, request, rc, a);
+               smack_log(subject_known->smk_known, object_label, request,
+                               rc, a);
 #endif
        return rc;
 }
@@ -198,20 +198,21 @@ out_audit:
 int smk_curacc(char *obj_label, u32 mode, struct smk_audit_info *a)
 {
        struct task_smack *tsp = current_security();
-       char *sp = smk_of_task(tsp);
+       struct smack_known *skp = smk_of_task(tsp);
        int may;
        int rc;
 
        /*
         * Check the global rule list
         */
-       rc = smk_access(sp, obj_label, mode, NULL);
+       rc = smk_access(skp, obj_label, mode, NULL);
        if (rc == 0) {
                /*
                 * If there is an entry in the task's rule list
                 * it can further restrict access.
                 */
-               may = smk_access_entry(sp, obj_label, &tsp->smk_rules);
+               may = smk_access_entry(skp->smk_known, obj_label,
+                                       &tsp->smk_rules);
                if (may < 0)
                        goto out_audit;
                if ((mode & may) == mode)
@@ -228,7 +229,7 @@ int smk_curacc(char *obj_label, u32 mode, struct smk_audit_info *a)
 out_audit:
 #ifdef CONFIG_AUDIT
        if (a)
-               smack_log(sp, obj_label, mode, rc, a);
+               smack_log(skp->smk_known, obj_label, mode, rc, a);
 #endif
        return rc;
 }
@@ -513,10 +514,10 @@ char *smk_import(const char *string, int len)
  * smack_from_secid - find the Smack label associated with a secid
  * @secid: an integer that might be associated with a Smack label
  *
- * Returns a pointer to the appropriate Smack label if there is one,
+ * Returns a pointer to the appropriate Smack label entry if there is one,
  * otherwise a pointer to the invalid Smack label.
  */
-char *smack_from_secid(const u32 secid)
+struct smack_known *smack_from_secid(const u32 secid)
 {
        struct smack_known *skp;
 
@@ -524,7 +525,7 @@ char *smack_from_secid(const u32 secid)
        list_for_each_entry_rcu(skp, &smack_known_list, list) {
                if (skp->smk_secid == secid) {
                        rcu_read_unlock();
-                       return skp->smk_known;
+                       return skp;
                }
        }
 
@@ -533,7 +534,7 @@ char *smack_from_secid(const u32 secid)
         * of a secid that is not on the list.
         */
        rcu_read_unlock();
-       return smack_known_invalid.smk_known;
+       return &smack_known_invalid;
 }
 
 /**