Commit f0641cba7729e5e14f82d2eedc398103f5fa31b1
Committed by
James Morris
1 parent
cea7daa358
Exists in
master
and in
7 other branches
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 |