lkml.org 
[lkml]   [2010]   [Apr]   [30]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[PATCH 3/7] KEYS: Use RCU dereference wrappers in keyring key type code
Date
The keyring key type code should use RCU dereference wrappers, even when it
holds the keyring's key semaphore.

Reported-by: Vegard Nossum <vegard.nossum@gmail.com>
Signed-off-by: David Howells <dhowells@redhat.com>
---

security/keys/keyring.c | 23 +++++++++++++----------
1 files changed, 13 insertions(+), 10 deletions(-)

diff --git a/security/keys/keyring.c b/security/keys/keyring.c
index d570824..63385af 100644
--- a/security/keys/keyring.c
+++ b/security/keys/keyring.c
@@ -20,6 +20,11 @@
#include <linux/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
@@ -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);
@@ -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;

@@ -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);
@@ -867,7 +868,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++)
@@ -958,7 +959,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,
@@ -990,7 +991,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);
@@ -1024,7 +1027,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;



\
 
 \ /
  Last update: 2010-04-30 20:41    [W:0.084 / U:0.188 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site