Commit f0641cba7729e5e14f82d2eedc398103f5fa31b1

Authored by David Howells
Committed by James Morris
1 parent cea7daa358

KEYS: Use RCU dereference wrappers in keyring key type code

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>
Acked-by: Serge Hallyn <serue@us.ibm.com>
Signed-off-by: James Morris <jmorris@namei.org>

Showing 1 changed file with 13 additions and 10 deletions Side-by-side Diff

security/keys/keyring.c
... ... @@ -20,6 +20,11 @@
20 20 #include <asm/uaccess.h>
21 21 #include "internal.h"
22 22  
  23 +#define rcu_dereference_locked_keyring(keyring) \
  24 + (rcu_dereference_protected( \
  25 + (keyring)->payload.subscriptions, \
  26 + rwsem_is_locked((struct rw_semaphore *)&(keyring)->sem)))
  27 +
23 28 /*
24 29 * when plumbing the depths of the key tree, this sets a hard limit set on how
25 30 * deep we're willing to go
... ... @@ -201,8 +206,7 @@
201 206 int loop, ret;
202 207  
203 208 ret = 0;
204   - klist = keyring->payload.subscriptions;
205   -
  209 + klist = rcu_dereference_locked_keyring(keyring);
206 210 if (klist) {
207 211 /* calculate how much data we could return */
208 212 qty = klist->nkeys * sizeof(key_serial_t);
... ... @@ -720,8 +724,7 @@
720 724 }
721 725  
722 726 /* see if there's a matching key we can displace */
723   - klist = keyring->payload.subscriptions;
724   -
  727 + klist = rcu_dereference_locked_keyring(keyring);
725 728 if (klist && klist->nkeys > 0) {
726 729 struct key_type *type = key->type;
727 730  
... ... @@ -765,8 +768,6 @@
765 768 if (ret < 0)
766 769 goto error2;
767 770  
768   - klist = keyring->payload.subscriptions;
769   -
770 771 if (klist && klist->nkeys < klist->maxkeys) {
771 772 /* there's sufficient slack space to add directly */
772 773 atomic_inc(&key->usage);
... ... @@ -868,7 +869,7 @@
868 869  
869 870 down_write(&keyring->sem);
870 871  
871   - klist = keyring->payload.subscriptions;
  872 + klist = rcu_dereference_locked_keyring(keyring);
872 873 if (klist) {
873 874 /* search the keyring for the key */
874 875 for (loop = 0; loop < klist->nkeys; loop++)
... ... @@ -959,7 +960,7 @@
959 960 /* detach the pointer block with the locks held */
960 961 down_write(&keyring->sem);
961 962  
962   - klist = keyring->payload.subscriptions;
  963 + klist = rcu_dereference_locked_keyring(keyring);
963 964 if (klist) {
964 965 /* adjust the quota */
965 966 key_payload_reserve(keyring,
966 967  
... ... @@ -991,8 +992,10 @@
991 992 */
992 993 static void keyring_revoke(struct key *keyring)
993 994 {
994   - struct keyring_list *klist = keyring->payload.subscriptions;
  995 + struct keyring_list *klist;
995 996  
  997 + klist = rcu_dereference_locked_keyring(keyring);
  998 +
996 999 /* adjust the quota */
997 1000 key_payload_reserve(keyring, 0);
998 1001  
... ... @@ -1025,7 +1028,7 @@
1025 1028  
1026 1029 down_write(&keyring->sem);
1027 1030  
1028   - klist = keyring->payload.subscriptions;
  1031 + klist = rcu_dereference_locked_keyring(keyring);
1029 1032 if (!klist)
1030 1033 goto no_klist;
1031 1034