summaryrefslogtreecommitdiffstats
path: root/security/keys/keyring.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/keys/keyring.c')
-rw-r--r--security/keys/keyring.c35
1 files changed, 31 insertions, 4 deletions
diff --git a/security/keys/keyring.c b/security/keys/keyring.c
index 88292e3dee96..70f0c313c888 100644
--- a/security/keys/keyring.c
+++ b/security/keys/keyring.c
@@ -292,7 +292,7 @@ key_ref_t keyring_search_aux(key_ref_t keyring_ref,
struct keyring_list *keylist;
struct timespec now;
- unsigned long possessed;
+ unsigned long possessed, kflags;
struct key *keyring, *key;
key_ref_t key_ref;
long err;
@@ -319,6 +319,32 @@ key_ref_t keyring_search_aux(key_ref_t keyring_ref,
err = -EAGAIN;
sp = 0;
+ /* firstly we should check to see if this top-level keyring is what we
+ * are looking for */
+ key_ref = ERR_PTR(-EAGAIN);
+ kflags = keyring->flags;
+ if (keyring->type == type && match(keyring, description)) {
+ key = keyring;
+
+ /* check it isn't negative and hasn't expired or been
+ * revoked */
+ if (kflags & (1 << KEY_FLAG_REVOKED))
+ goto error_2;
+ if (key->expiry && now.tv_sec >= key->expiry)
+ goto error_2;
+ key_ref = ERR_PTR(-ENOKEY);
+ if (kflags & (1 << KEY_FLAG_NEGATIVE))
+ goto error_2;
+ goto found;
+ }
+
+ /* otherwise, the top keyring must not be revoked, expired, or
+ * negatively instantiated if we are to search it */
+ key_ref = ERR_PTR(-EAGAIN);
+ if (kflags & ((1 << KEY_FLAG_REVOKED) | (1 << KEY_FLAG_NEGATIVE)) ||
+ (keyring->expiry && now.tv_sec >= keyring->expiry))
+ goto error_2;
+
/* start processing a new keyring */
descend:
if (test_bit(KEY_FLAG_REVOKED, &keyring->flags))
@@ -331,13 +357,14 @@ descend:
/* iterate through the keys in this keyring first */
for (kix = 0; kix < keylist->nkeys; kix++) {
key = keylist->keys[kix];
+ kflags = key->flags;
/* ignore keys not of this type */
if (key->type != type)
continue;
/* skip revoked keys and expired keys */
- if (test_bit(KEY_FLAG_REVOKED, &key->flags))
+ if (kflags & (1 << KEY_FLAG_REVOKED))
continue;
if (key->expiry && now.tv_sec >= key->expiry)
@@ -352,8 +379,8 @@ descend:
context, KEY_SEARCH) < 0)
continue;
- /* we set a different error code if we find a negative key */
- if (test_bit(KEY_FLAG_NEGATIVE, &key->flags)) {
+ /* we set a different error code if we pass a negative key */
+ if (kflags & (1 << KEY_FLAG_NEGATIVE)) {
err = -ENOKEY;
continue;
}