]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - security/keys/keyring.c
KEYS: keyring_serialise_link_sem is only needed for keyring->keyring links
[mv-sheeva.git] / security / keys / keyring.c
index e814d2109f8ef170ea60043fa83b1f37c3e35de1..29de5ee3457bd305676fca8a7c56a0613c6d0d8e 100644 (file)
@@ -17,7 +17,7 @@
 #include <linux/seq_file.h>
 #include <linux/err.h>
 #include <keys/keyring-type.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 #include "internal.h"
 
 /*
@@ -39,7 +39,7 @@ static inline unsigned keyring_hash(const char *desc)
        unsigned bucket = 0;
 
        for (; *desc; desc++)
-               bucket += (unsigned char) *desc;
+               bucket += (unsigned char)*desc;
 
        return bucket & (KEYRING_NAME_HASH_SIZE - 1);
 }
@@ -170,12 +170,10 @@ static void keyring_describe(const struct key *keyring, struct seq_file *m)
 {
        struct keyring_list *klist;
 
-       if (keyring->description) {
+       if (keyring->description)
                seq_puts(m, keyring->description);
-       }
-       else {
+       else
                seq_puts(m, "[anon]");
-       }
 
        rcu_read_lock();
        klist = rcu_dereference(keyring->payload.subscriptions);
@@ -201,7 +199,7 @@ static long keyring_read(const struct key *keyring,
        int loop, ret;
 
        ret = 0;
-       klist = rcu_dereference(keyring->payload.subscriptions);
+       klist = keyring->payload.subscriptions;
 
        if (klist) {
                /* calculate how much data we could return */
@@ -237,7 +235,7 @@ static long keyring_read(const struct key *keyring,
                ret = qty;
        }
 
- error:
+error:
        return ret;
 
 } /* end keyring_read() */
@@ -306,7 +304,7 @@ key_ref_t keyring_search_aux(key_ref_t keyring_ref,
        key_check(keyring);
 
        /* top keyring must have search permission to begin the search */
-        err = key_task_permission(keyring_ref, cred, KEY_SEARCH);
+       err = key_task_permission(keyring_ref, cred, KEY_SEARCH);
        if (err < 0) {
                key_ref = ERR_PTR(err);
                goto error;
@@ -508,7 +506,7 @@ key_ref_t __keyring_search_one(key_ref_t keyring_ref,
        rcu_read_unlock();
        return ERR_PTR(-ENOKEY);
 
- found:
+found:
        atomic_inc(&key->usage);
        rcu_read_unlock();
        return make_key_ref(key, possessed);
@@ -565,7 +563,7 @@ struct key *find_keyring_by_name(const char *name, bool skip_perm_check)
        read_unlock(&keyring_name_lock);
        keyring = ERR_PTR(-ENOKEY);
 
- error:
+error:
        return keyring;
 
 } /* end find_keyring_by_name() */
@@ -598,7 +596,7 @@ static int keyring_detect_cycle(struct key *A, struct key *B)
        sp = 0;
 
        /* start processing a new keyring */
- descend:
+descend:
        if (test_bit(KEY_FLAG_REVOKED, &subtree->flags))
                goto not_this_keyring;
 
@@ -607,7 +605,7 @@ static int keyring_detect_cycle(struct key *A, struct key *B)
                goto not_this_keyring;
        kix = 0;
 
- ascend:
+ascend:
        /* iterate through the remaining keys in this keyring */
        for (; kix < keylist->nkeys; kix++) {
                key = keylist->keys[kix];
@@ -633,7 +631,7 @@ static int keyring_detect_cycle(struct key *A, struct key *B)
 
        /* the keyring we're looking at was disqualified or didn't contain a
         * matching key */
- not_this_keyring:
+not_this_keyring:
        if (sp > 0) {
                /* resume the checking of a keyring higher up in the tree */
                sp--;
@@ -644,15 +642,15 @@ static int keyring_detect_cycle(struct key *A, struct key *B)
 
        ret = 0; /* no cycles detected */
 
- error:
+error:
        rcu_read_unlock();
        return ret;
 
- too_deep:
+too_deep:
        ret = -ELOOP;
        goto error;
 
- cycle_detected:
+cycle_detected:
        ret = -EDEADLK;
        goto error;
 
@@ -707,13 +705,14 @@ int __key_link(struct key *keyring, struct key *key)
        if (keyring->type != &key_type_keyring)
                goto error;
 
-       /* serialise link/link calls to prevent parallel calls causing a
-        * cycle when applied to two keyring in opposite orders */
-       down_write(&keyring_serialise_link_sem);
-
-       /* check that we aren't going to create a cycle adding one keyring to
-        * another */
+       /* do some special keyring->keyring link checks */
        if (key->type == &key_type_keyring) {
+               /* serialise link/link calls to prevent parallel calls causing
+                * a cycle when applied to two keyring in opposite orders */
+               down_write(&keyring_serialise_link_sem);
+
+               /* check that we aren't going to create a cycle adding one
+                * keyring to another */
                ret = keyring_detect_cycle(keyring, key);
                if (ret < 0)
                        goto error2;
@@ -775,8 +774,7 @@ int __key_link(struct key *keyring, struct key *key)
                smp_wmb();
                klist->nkeys++;
                smp_wmb();
-       }
-       else {
+       } else {
                /* grow the key list */
                max = 4;
                if (klist)
@@ -817,7 +815,8 @@ int __key_link(struct key *keyring, struct key *key)
 done:
        ret = 0;
 error2:
-       up_write(&keyring_serialise_link_sem);
+       if (key->type == &key_type_keyring)
+               up_write(&keyring_serialise_link_sem);
 error:
        return ret;