Merge branch 'next-queue' into next
authorJames Morris <jmorris@namei.org>
Tue, 29 Mar 2011 21:51:46 +0000 (08:51 +1100)
committerJames Morris <jmorris@namei.org>
Tue, 29 Mar 2011 21:51:46 +0000 (08:51 +1100)
include/linux/key.h
net/dns_resolver/dns_key.c
security/Kconfig
security/keys/internal.h
security/keys/keyctl.c
security/keys/keyring.c
security/keys/proc.c
security/keys/process_keys.c
security/keys/request_key.c
security/keys/request_key_auth.c
security/keys/user_defined.c

index b2bb01719561f0d3de11945a9dba0a78744b8acc..ef19b99aff98d426c8e9b355a31360675daf9669 100644 (file)
@@ -276,6 +276,19 @@ static inline key_serial_t key_serial(struct key *key)
        return key ? key->serial : 0;
 }
 
+/**
+ * key_is_instantiated - Determine if a key has been positively instantiated
+ * @key: The key to check.
+ *
+ * Return true if the specified key has been positively instantiated, false
+ * otherwise.
+ */
+static inline bool key_is_instantiated(const struct key *key)
+{
+       return test_bit(KEY_FLAG_INSTANTIATED, &key->flags) &&
+               !test_bit(KEY_FLAG_NEGATIVE, &key->flags);
+}
+
 #define rcu_dereference_key(KEY)                                       \
        (rcu_dereference_protected((KEY)->payload.rcudata,              \
                                   rwsem_is_locked(&((struct key *)(KEY))->sem)))
index cfa7a5e1c5c98ca4592e09588a3a80bc1ba24d10..fa000d26dc6097220fe8bf53ed7cfc822afc31a0 100644 (file)
@@ -212,10 +212,12 @@ static void dns_resolver_describe(const struct key *key, struct seq_file *m)
        int err = key->type_data.x[0];
 
        seq_puts(m, key->description);
-       if (err)
-               seq_printf(m, ": %d", err);
-       else
-               seq_printf(m, ": %u", key->datalen);
+       if (key_is_instantiated(key)) {
+               if (err)
+                       seq_printf(m, ": %d", err);
+               else
+                       seq_printf(m, ": %u", key->datalen);
+       }
 }
 
 /*
index 95accd442d55eeb5c81f6bcd39b63fc12e5a6f25..e0f08b52e4ab440933c9f72120092b8bcd527b46 100644 (file)
@@ -167,6 +167,7 @@ config INTEL_TXT
 config LSM_MMAP_MIN_ADDR
        int "Low address space for LSM to protect from user allocation"
        depends on SECURITY && SECURITY_SELINUX
+       default 32768 if ARM
        default 65536
        help
          This is the portion of low virtual memory which should be protected
index 07a025f8190233faf66a384816dea03754ee770a..f375152a2500b1d747d7128517430d2401f3a4ce 100644 (file)
@@ -109,11 +109,13 @@ extern key_ref_t keyring_search_aux(key_ref_t keyring_ref,
                                    const struct cred *cred,
                                    struct key_type *type,
                                    const void *description,
-                                   key_match_func_t match);
+                                   key_match_func_t match,
+                                   bool no_state_check);
 
 extern key_ref_t search_my_process_keyrings(struct key_type *type,
                                            const void *description,
                                            key_match_func_t match,
+                                           bool no_state_check,
                                            const struct cred *cred);
 extern key_ref_t search_process_keyrings(struct key_type *type,
                                         const void *description,
index 427fddcaeb19b78049b3e1028349cb6b731ed8f9..eca51918c951d3a28db16bf0f61c749722b6ac64 100644 (file)
@@ -206,8 +206,14 @@ SYSCALL_DEFINE4(request_key, const char __user *, _type,
                goto error5;
        }
 
+       /* wait for the key to finish being constructed */
+       ret = wait_for_key_construction(key, 1);
+       if (ret < 0)
+               goto error6;
+
        ret = key->serial;
 
+error6:
        key_put(key);
 error5:
        key_type_put(ktype);
index cdd2f3f88c8879280a7607c1be655d5487d652c4..a06ffab38568809f5187970261888d6a9e673f18 100644 (file)
@@ -176,13 +176,15 @@ static void keyring_describe(const struct key *keyring, struct seq_file *m)
        else
                seq_puts(m, "[anon]");
 
-       rcu_read_lock();
-       klist = rcu_dereference(keyring->payload.subscriptions);
-       if (klist)
-               seq_printf(m, ": %u/%u", klist->nkeys, klist->maxkeys);
-       else
-               seq_puts(m, ": empty");
-       rcu_read_unlock();
+       if (key_is_instantiated(keyring)) {
+               rcu_read_lock();
+               klist = rcu_dereference(keyring->payload.subscriptions);
+               if (klist)
+                       seq_printf(m, ": %u/%u", klist->nkeys, klist->maxkeys);
+               else
+                       seq_puts(m, ": empty");
+               rcu_read_unlock();
+       }
 }
 
 /*
@@ -271,6 +273,7 @@ struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid,
  * @type: The type of key to search for.
  * @description: Parameter for @match.
  * @match: Function to rule on whether or not a key is the one required.
+ * @no_state_check: Don't check if a matching key is bad
  *
  * Search the supplied keyring tree for a key that matches the criteria given.
  * The root keyring and any linked keyrings must grant Search permission to the
@@ -303,7 +306,8 @@ key_ref_t keyring_search_aux(key_ref_t keyring_ref,
                             const struct cred *cred,
                             struct key_type *type,
                             const void *description,
-                            key_match_func_t match)
+                            key_match_func_t match,
+                            bool no_state_check)
 {
        struct {
                struct keyring_list *keylist;
@@ -345,6 +349,8 @@ key_ref_t keyring_search_aux(key_ref_t keyring_ref,
        kflags = keyring->flags;
        if (keyring->type == type && match(keyring, description)) {
                key = keyring;
+               if (no_state_check)
+                       goto found;
 
                /* check it isn't negative and hasn't expired or been
                 * revoked */
@@ -384,11 +390,13 @@ descend:
                        continue;
 
                /* skip revoked keys and expired keys */
-               if (kflags & (1 << KEY_FLAG_REVOKED))
-                       continue;
+               if (!no_state_check) {
+                       if (kflags & (1 << KEY_FLAG_REVOKED))
+                               continue;
 
-               if (key->expiry && now.tv_sec >= key->expiry)
-                       continue;
+                       if (key->expiry && now.tv_sec >= key->expiry)
+                               continue;
+               }
 
                /* keys that don't match */
                if (!match(key, description))
@@ -399,6 +407,9 @@ descend:
                                        cred, KEY_SEARCH) < 0)
                        continue;
 
+               if (no_state_check)
+                       goto found;
+
                /* we set a different error code if we pass a negative key */
                if (kflags & (1 << KEY_FLAG_NEGATIVE)) {
                        err = key->type_data.reject_error;
@@ -478,7 +489,7 @@ key_ref_t keyring_search(key_ref_t keyring,
                return ERR_PTR(-ENOKEY);
 
        return keyring_search_aux(keyring, current->cred,
-                                 type, description, type->match);
+                                 type, description, type->match, false);
 }
 EXPORT_SYMBOL(keyring_search);
 
index 525cf8a29cdde86c5c58557fd73ceb49e9c73dec..49bbc97943ad8b804e22ff69150083a0f891ffd5 100644 (file)
@@ -199,7 +199,7 @@ static int proc_keys_show(struct seq_file *m, void *v)
        if (key->perm & KEY_POS_VIEW) {
                skey_ref = search_my_process_keyrings(key->type, key,
                                                      lookup_user_key_possessed,
-                                                     cred);
+                                                     true, cred);
                if (!IS_ERR(skey_ref)) {
                        key_ref_put(skey_ref);
                        key_ref = make_key_ref(key, 1);
index 930634e4514973ac0f79acc7037138acb576a2c3..6c0480db8885b6393b8f4bfea75b8d35ce3015d3 100644 (file)
@@ -331,6 +331,7 @@ void key_fsgid_changed(struct task_struct *tsk)
 key_ref_t search_my_process_keyrings(struct key_type *type,
                                     const void *description,
                                     key_match_func_t match,
+                                    bool no_state_check,
                                     const struct cred *cred)
 {
        key_ref_t key_ref, ret, err;
@@ -350,7 +351,7 @@ key_ref_t search_my_process_keyrings(struct key_type *type,
        if (cred->thread_keyring) {
                key_ref = keyring_search_aux(
                        make_key_ref(cred->thread_keyring, 1),
-                       cred, type, description, match);
+                       cred, type, description, match, no_state_check);
                if (!IS_ERR(key_ref))
                        goto found;
 
@@ -371,7 +372,7 @@ key_ref_t search_my_process_keyrings(struct key_type *type,
        if (cred->tgcred->process_keyring) {
                key_ref = keyring_search_aux(
                        make_key_ref(cred->tgcred->process_keyring, 1),
-                       cred, type, description, match);
+                       cred, type, description, match, no_state_check);
                if (!IS_ERR(key_ref))
                        goto found;
 
@@ -395,7 +396,7 @@ key_ref_t search_my_process_keyrings(struct key_type *type,
                        make_key_ref(rcu_dereference(
                                             cred->tgcred->session_keyring),
                                     1),
-                       cred, type, description, match);
+                       cred, type, description, match, no_state_check);
                rcu_read_unlock();
 
                if (!IS_ERR(key_ref))
@@ -417,7 +418,7 @@ key_ref_t search_my_process_keyrings(struct key_type *type,
        else if (cred->user->session_keyring) {
                key_ref = keyring_search_aux(
                        make_key_ref(cred->user->session_keyring, 1),
-                       cred, type, description, match);
+                       cred, type, description, match, no_state_check);
                if (!IS_ERR(key_ref))
                        goto found;
 
@@ -459,7 +460,8 @@ key_ref_t search_process_keyrings(struct key_type *type,
 
        might_sleep();
 
-       key_ref = search_my_process_keyrings(type, description, match, cred);
+       key_ref = search_my_process_keyrings(type, description, match,
+                                            false, cred);
        if (!IS_ERR(key_ref))
                goto found;
        err = key_ref;
index df3c0417ee4062ffebac5cb6f3ad30d84fc66a6b..b18a71745901811120e51e6b33624b9e77a98891 100644 (file)
@@ -530,8 +530,7 @@ struct key *request_key_and_link(struct key_type *type,
               dest_keyring, flags);
 
        /* search all the process keyrings for a key */
-       key_ref = search_process_keyrings(type, description, type->match,
-                                         cred);
+       key_ref = search_process_keyrings(type, description, type->match, cred);
 
        if (!IS_ERR(key_ref)) {
                key = key_ref_to_ptr(key_ref);
index 68164031a74e0bc225844037ceedd45a40fc94cb..f6337c9082ebf6eae8cc0292c6042e5a6350f70f 100644 (file)
@@ -59,7 +59,8 @@ static void request_key_auth_describe(const struct key *key,
 
        seq_puts(m, "key:");
        seq_puts(m, key->description);
-       seq_printf(m, " pid:%d ci:%zu", rka->pid, rka->callout_len);
+       if (key_is_instantiated(key))
+               seq_printf(m, " pid:%d ci:%zu", rka->pid, rka->callout_len);
 }
 
 /*
index c6ca8662a4685bd162205938eafae39bef25fbbf..63bb1aaffc0a056d316d5631b14dc761467c7534 100644 (file)
@@ -169,8 +169,8 @@ EXPORT_SYMBOL_GPL(user_destroy);
 void user_describe(const struct key *key, struct seq_file *m)
 {
        seq_puts(m, key->description);
-
-       seq_printf(m, ": %u", key->datalen);
+       if (key_is_instantiated(key))
+               seq_printf(m, ": %u", key->datalen);
 }
 
 EXPORT_SYMBOL_GPL(user_describe);