Skip to content

Commit

Permalink
KEYS: Use RCU dereference wrappers in keyring key type code
Browse files Browse the repository at this point in the history
The keyring key type code should use RCU dereference wrappers, even when it
holds the keyring's key semaphore.

Reported-by: Vegard Nossum <[email protected]>
Signed-off-by: David Howells <[email protected]>
Acked-by: Serge Hallyn <[email protected]>
Signed-off-by: James Morris <[email protected]>
  • Loading branch information
dhowells authored and James Morris committed May 5, 2010
1 parent cea7daa commit f0641cb
Showing 1 changed file with 13 additions and 10 deletions.
23 changes: 13 additions & 10 deletions security/keys/keyring.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@
#include <asm/uaccess.h>
#include "internal.h"

#define rcu_dereference_locked_keyring(keyring) \
(rcu_dereference_protected( \
(keyring)->payload.subscriptions, \
rwsem_is_locked((struct rw_semaphore *)&(keyring)->sem)))

/*
* when plumbing the depths of the key tree, this sets a hard limit set on how
* deep we're willing to go
Expand Down Expand Up @@ -201,8 +206,7 @@ static long keyring_read(const struct key *keyring,
int loop, ret;

ret = 0;
klist = keyring->payload.subscriptions;

klist = rcu_dereference_locked_keyring(keyring);
if (klist) {
/* calculate how much data we could return */
qty = klist->nkeys * sizeof(key_serial_t);
Expand Down Expand Up @@ -720,8 +724,7 @@ int __key_link(struct key *keyring, struct key *key)
}

/* see if there's a matching key we can displace */
klist = keyring->payload.subscriptions;

klist = rcu_dereference_locked_keyring(keyring);
if (klist && klist->nkeys > 0) {
struct key_type *type = key->type;

Expand Down Expand Up @@ -765,8 +768,6 @@ int __key_link(struct key *keyring, struct key *key)
if (ret < 0)
goto error2;

klist = keyring->payload.subscriptions;

if (klist && klist->nkeys < klist->maxkeys) {
/* there's sufficient slack space to add directly */
atomic_inc(&key->usage);
Expand Down Expand Up @@ -868,7 +869,7 @@ int key_unlink(struct key *keyring, struct key *key)

down_write(&keyring->sem);

klist = keyring->payload.subscriptions;
klist = rcu_dereference_locked_keyring(keyring);
if (klist) {
/* search the keyring for the key */
for (loop = 0; loop < klist->nkeys; loop++)
Expand Down Expand Up @@ -959,7 +960,7 @@ int keyring_clear(struct key *keyring)
/* detach the pointer block with the locks held */
down_write(&keyring->sem);

klist = keyring->payload.subscriptions;
klist = rcu_dereference_locked_keyring(keyring);
if (klist) {
/* adjust the quota */
key_payload_reserve(keyring,
Expand Down Expand Up @@ -991,7 +992,9 @@ EXPORT_SYMBOL(keyring_clear);
*/
static void keyring_revoke(struct key *keyring)
{
struct keyring_list *klist = keyring->payload.subscriptions;
struct keyring_list *klist;

klist = rcu_dereference_locked_keyring(keyring);

/* adjust the quota */
key_payload_reserve(keyring, 0);
Expand Down Expand Up @@ -1025,7 +1028,7 @@ void keyring_gc(struct key *keyring, time_t limit)

down_write(&keyring->sem);

klist = keyring->payload.subscriptions;
klist = rcu_dereference_locked_keyring(keyring);
if (!klist)
goto no_klist;

Expand Down

0 comments on commit f0641cb

Please sign in to comment.