KEYS: Skip key state checks when checking for possession
authorDavid Howells <dhowells@redhat.com>
Tue, 24 Sep 2013 09:35:13 +0000 (10:35 +0100)
committerDavid Howells <dhowells@redhat.com>
Tue, 24 Sep 2013 09:35:13 +0000 (10:35 +0100)
Skip key state checks (invalidation, revocation and expiration) when checking
for possession.  Without this, keys that have been marked invalid, revoked
keys and expired keys are not given a possession attribute - which means the
possessor is not granted any possession permits and cannot do anything with
them unless they also have one a user, group or other permit.

This causes failures in the keyutils test suite's revocation and expiration
tests now that commit 96b5c8fea6c0861621051290d705ec2e971963f1 reduced the
initial permissions granted to a key.

The failures are due to accesses to revoked and expired keys being given
EACCES instead of EKEYREVOKED or EKEYEXPIRED.

Signed-off-by: David Howells <dhowells@redhat.com>
security/keys/internal.h
security/keys/process_keys.c
security/keys/request_key.c
security/keys/request_key_auth.c

index d4f1468b9b50f46cd7d739544902a77a3ff40384..df971feceaf2202335a1488e07adf1a97dd03939 100644 (file)
@@ -124,6 +124,7 @@ extern key_ref_t search_my_process_keyrings(struct key_type *type,
 extern key_ref_t search_process_keyrings(struct key_type *type,
                                         const void *description,
                                         key_match_func_t match,
+                                        bool no_state_check,
                                         const struct cred *cred);
 
 extern struct key *find_keyring_by_name(const char *name, bool skip_perm_check);
index 42defae1e161632e93b13b8194af1a30a09f2492..a3410d605849923088deed4684473ce5aa37b055 100644 (file)
@@ -440,6 +440,7 @@ found:
 key_ref_t search_process_keyrings(struct key_type *type,
                                  const void *description,
                                  key_match_func_t match,
+                                 bool no_state_check,
                                  const struct cred *cred)
 {
        struct request_key_auth *rka;
@@ -448,7 +449,7 @@ key_ref_t search_process_keyrings(struct key_type *type,
        might_sleep();
 
        key_ref = search_my_process_keyrings(type, description, match,
-                                            false, cred);
+                                            no_state_check, cred);
        if (!IS_ERR(key_ref))
                goto found;
        err = key_ref;
@@ -468,7 +469,8 @@ key_ref_t search_process_keyrings(struct key_type *type,
                        rka = cred->request_key_auth->payload.data;
 
                        key_ref = search_process_keyrings(type, description,
-                                                         match, rka->cred);
+                                                         match, no_state_check,
+                                                         rka->cred);
 
                        up_read(&cred->request_key_auth->sem);
 
@@ -675,7 +677,7 @@ try_again:
                /* check to see if we possess the key */
                skey_ref = search_process_keyrings(key->type, key,
                                                   lookup_user_key_possessed,
-                                                  cred);
+                                                  true, cred);
 
                if (!IS_ERR(skey_ref)) {
                        key_put(key);
index c411f9bb156b205751ae06983e85f547119a245f..172115b38054f0975dbffc7aebb60d440271b03c 100644 (file)
@@ -390,7 +390,8 @@ static int construct_alloc_key(struct key_type *type,
         * waited for locks */
        mutex_lock(&key_construction_mutex);
 
-       key_ref = search_process_keyrings(type, description, type->match, cred);
+       key_ref = search_process_keyrings(type, description, type->match,
+                                         false, cred);
        if (!IS_ERR(key_ref))
                goto key_already_present;
 
@@ -539,7 +540,8 @@ 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,
+                                         false, cred);
 
        if (!IS_ERR(key_ref)) {
                key = key_ref_to_ptr(key_ref);
index 85730d5a5a59a05c852b3d22c586778b117589fa..92077de555dfd5d337a3c9577b83d62102afc989 100644 (file)
@@ -247,7 +247,7 @@ struct key *key_get_instantiation_authkey(key_serial_t target_id)
                &key_type_request_key_auth,
                (void *) (unsigned long) target_id,
                key_get_instantiation_authkey_match,
-               cred);
+               false, cred);
 
        if (IS_ERR(authkey_ref)) {
                authkey = ERR_CAST(authkey_ref);