summaryrefslogtreecommitdiff
path: root/security/keys/keyring.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/keys/keyring.c')
-rw-r--r--security/keys/keyring.c17
1 files changed, 10 insertions, 7 deletions
diff --git a/security/keys/keyring.c b/security/keys/keyring.c
index b39038f7dd31..15bf4af8f282 100644
--- a/security/keys/keyring.c
+++ b/security/keys/keyring.c
@@ -271,6 +271,7 @@ static unsigned long keyring_get_key_chunk(const void *data, int level)
unsigned long chunk = 0;
const u8 *d;
int desc_len = index_key->desc_len, n = sizeof(chunk);
+ unsigned int offset;
level /= ASSOC_ARRAY_KEY_CHUNK_SIZE;
switch (level) {
@@ -284,17 +285,18 @@ static unsigned long keyring_get_key_chunk(const void *data, int level)
return (unsigned long)index_key->domain_tag;
default:
level -= 4;
- if (desc_len <= sizeof(index_key->desc))
+ offset = sizeof(index_key->desc) + level * sizeof(long);
+ if (desc_len <= offset)
return 0;
- d = index_key->description + sizeof(index_key->desc);
- d += level * sizeof(long);
- desc_len -= sizeof(index_key->desc);
+ d = index_key->description + offset;
+ desc_len -= offset;
if (desc_len > n)
desc_len = n;
+ d += desc_len;
do {
chunk <<= 8;
- chunk |= *d++;
+ chunk |= *--d;
} while (--desc_len > 0);
return chunk;
}
@@ -375,7 +377,7 @@ same:
return -1;
differ_plus_i:
- level += i;
+ level += i - (int)sizeof(a->desc);
differ:
i = level * 8 + __ffs(seg_a ^ seg_b);
return i;
@@ -576,7 +578,7 @@ static int keyring_search_iterator(const void *object, void *iterator_data)
struct keyring_search_context *ctx = iterator_data;
const struct key *key = keyring_ptr_to_key(object);
unsigned long kflags = READ_ONCE(key->flags);
- short state = READ_ONCE(key->state);
+ short state = key_read_state(key);
kenter("{%d}", key->serial);
@@ -1109,6 +1111,7 @@ key_ref_t find_key_to_update(key_ref_t keyring_ref,
kenter("{%d},{%s,%s}",
keyring->serial, index_key->type->name, index_key->description);
+ guard(rcu)();
object = assoc_array_find(&keyring->keys, &keyring_assoc_array_ops,
index_key);