Merge branches 'acpi-hotplug', 'acpi-sysfs' and 'acpi-sleep'
[firefly-linux-kernel-4.4.55.git] / security / smack / smack_access.c
index 6a0377f38620acd318444a399c2fc4ef8227c3db..14293cd9b1e53b4a260e9258a5cad54c75d71204 100644 (file)
@@ -84,6 +84,8 @@ int log_policy = SMACK_AUDIT_DENIED;
  *
  * Do the object check first because that is more
  * likely to differ.
+ *
+ * Allowing write access implies allowing locking.
  */
 int smk_access_entry(char *subject_label, char *object_label,
                        struct list_head *rule_list)
@@ -99,6 +101,11 @@ int smk_access_entry(char *subject_label, char *object_label,
                }
        }
 
+       /*
+        * MAY_WRITE implies MAY_LOCK.
+        */
+       if ((may & MAY_WRITE) == MAY_WRITE)
+               may |= MAY_LOCK;
        return may;
 }
 
@@ -245,6 +252,7 @@ out_audit:
 static inline void smack_str_from_perm(char *string, int access)
 {
        int i = 0;
+
        if (access & MAY_READ)
                string[i++] = 'r';
        if (access & MAY_WRITE)
@@ -255,6 +263,8 @@ static inline void smack_str_from_perm(char *string, int access)
                string[i++] = 'a';
        if (access & MAY_TRANSMUTE)
                string[i++] = 't';
+       if (access & MAY_LOCK)
+               string[i++] = 'l';
        string[i] = '\0';
 }
 /**
@@ -325,6 +335,25 @@ void smack_log(char *subject_label, char *object_label, int request,
 
 DEFINE_MUTEX(smack_known_lock);
 
+struct hlist_head smack_known_hash[SMACK_HASH_SLOTS];
+
+/**
+ * smk_insert_entry - insert a smack label into a hash map,
+ *
+ * this function must be called under smack_known_lock
+ */
+void smk_insert_entry(struct smack_known *skp)
+{
+       unsigned int hash;
+       struct hlist_head *head;
+
+       hash = full_name_hash(skp->smk_known, strlen(skp->smk_known));
+       head = &smack_known_hash[hash & (SMACK_HASH_SLOTS - 1)];
+
+       hlist_add_head_rcu(&skp->smk_hashed, head);
+       list_add_rcu(&skp->list, &smack_known_list);
+}
+
 /**
  * smk_find_entry - find a label on the list, return the list entry
  * @string: a text string that might be a Smack label
@@ -334,12 +363,16 @@ DEFINE_MUTEX(smack_known_lock);
  */
 struct smack_known *smk_find_entry(const char *string)
 {
+       unsigned int hash;
+       struct hlist_head *head;
        struct smack_known *skp;
 
-       list_for_each_entry_rcu(skp, &smack_known_list, list) {
+       hash = full_name_hash(string, strlen(string));
+       head = &smack_known_hash[hash & (SMACK_HASH_SLOTS - 1)];
+
+       hlist_for_each_entry_rcu(skp, head, smk_hashed)
                if (strcmp(skp->smk_known, string) == 0)
                        return skp;
-       }
 
        return NULL;
 }
@@ -475,7 +508,7 @@ struct smack_known *smk_import_entry(const char *string, int len)
                 * Make sure that the entry is actually
                 * filled before putting it on the list.
                 */
-               list_add_rcu(&skp->list, &smack_known_list);
+               smk_insert_entry(skp);
                goto unlockout;
        }
        /*