aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-05-04 21:49:34 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-05-04 21:49:34 -0400
commit67bff7c087f91f79dfa97a33a3aeb147eb467093 (patch)
tree6114aa6af653deee4b8098341c42ed3635b44c3f
parent7572e56314a7e2568f7196862222b45cfb9d6eda (diff)
parentcf8304e8f380903de3a15dc6ebd551c9e6cf1a21 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/security-testing-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/security-testing-2.6: KEYS: Fix RCU handling in key_gc_keyring() KEYS: Fix an RCU warning in the reading of user keys
-rw-r--r--security/keys/gc.c9
-rw-r--r--security/keys/user_defined.c3
2 files changed, 8 insertions, 4 deletions
diff --git a/security/keys/gc.c b/security/keys/gc.c
index 19902319d097..a46e825cbf02 100644
--- a/security/keys/gc.c
+++ b/security/keys/gc.c
@@ -77,10 +77,10 @@ static bool key_gc_keyring(struct key *keyring, time_t limit)
77 goto dont_gc; 77 goto dont_gc;
78 78
79 /* scan the keyring looking for dead keys */ 79 /* scan the keyring looking for dead keys */
80 klist = rcu_dereference_check(keyring->payload.subscriptions, 80 rcu_read_lock();
81 lockdep_is_held(&key_serial_lock)); 81 klist = rcu_dereference(keyring->payload.subscriptions);
82 if (!klist) 82 if (!klist)
83 goto dont_gc; 83 goto unlock_dont_gc;
84 84
85 for (loop = klist->nkeys - 1; loop >= 0; loop--) { 85 for (loop = klist->nkeys - 1; loop >= 0; loop--) {
86 key = klist->keys[loop]; 86 key = klist->keys[loop];
@@ -89,11 +89,14 @@ static bool key_gc_keyring(struct key *keyring, time_t limit)
89 goto do_gc; 89 goto do_gc;
90 } 90 }
91 91
92unlock_dont_gc:
93 rcu_read_unlock();
92dont_gc: 94dont_gc:
93 kleave(" = false"); 95 kleave(" = false");
94 return false; 96 return false;
95 97
96do_gc: 98do_gc:
99 rcu_read_unlock();
97 key_gc_cursor = keyring->serial; 100 key_gc_cursor = keyring->serial;
98 key_get(keyring); 101 key_get(keyring);
99 spin_unlock(&key_serial_lock); 102 spin_unlock(&key_serial_lock);
diff --git a/security/keys/user_defined.c b/security/keys/user_defined.c
index 7c687d568221..e9aa07929656 100644
--- a/security/keys/user_defined.c
+++ b/security/keys/user_defined.c
@@ -199,7 +199,8 @@ long user_read(const struct key *key, char __user *buffer, size_t buflen)
199 struct user_key_payload *upayload; 199 struct user_key_payload *upayload;
200 long ret; 200 long ret;
201 201
202 upayload = rcu_dereference(key->payload.data); 202 upayload = rcu_dereference_protected(
203 key->payload.data, rwsem_is_locked(&((struct key *)key)->sem));
203 ret = upayload->datalen; 204 ret = upayload->datalen;
204 205
205 /* we can return the data as is */ 206 /* we can return the data as is */