* [PATCH 1/3] KEYS: Add missing smp_rmb() primitives to the keyring search code
@ 2012-01-17 20:39 David Howells
2012-01-17 20:39 ` [PATCH 2/3] keys: fix trusted/encrypted keys sparse rcu_assign_pointer messages David Howells
2012-01-17 20:40 ` [PATCH 3/3] encrypted-keys: fix rcu and sparse messages David Howells
0 siblings, 2 replies; 3+ messages in thread
From: David Howells @ 2012-01-17 20:39 UTC (permalink / raw)
To: jmorris
Cc: keyrings, linux-security-module, linux-kernel, stable, David Howells
Add missing smp_rmb() primitives to the keyring search code.
When keyring payloads are appended to without replacement (thus using up spare
slots in the key pointer array), an smp_wmb() is issued between the pointer
assignment and the increment of the key count (nkeys).
There should be corresponding read barriers between the read of nkeys and
dereferences of keys[n] when n is dependent on the value of nkeys.
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
---
security/keys/gc.c | 4 +++-
security/keys/keyring.c | 22 +++++++++++++++-------
2 files changed, 18 insertions(+), 8 deletions(-)
diff --git a/security/keys/gc.c b/security/keys/gc.c
index bf4d8da..a42b455 100644
--- a/security/keys/gc.c
+++ b/security/keys/gc.c
@@ -145,7 +145,9 @@ static void key_gc_keyring(struct key *keyring, time_t limit)
if (!klist)
goto unlock_dont_gc;
- for (loop = klist->nkeys - 1; loop >= 0; loop--) {
+ loop = klist->nkeys;
+ smp_rmb();
+ for (loop--; loop >= 0; loop--) {
key = klist->keys[loop];
if (test_bit(KEY_FLAG_DEAD, &key->flags) ||
(key->expiry > 0 && key->expiry <= limit))
diff --git a/security/keys/keyring.c b/security/keys/keyring.c
index 37a7f3b..d605f75 100644
--- a/security/keys/keyring.c
+++ b/security/keys/keyring.c
@@ -319,7 +319,7 @@ key_ref_t keyring_search_aux(key_ref_t keyring_ref,
struct key *keyring, *key;
key_ref_t key_ref;
long err;
- int sp, kix;
+ int sp, nkeys, kix;
keyring = key_ref_to_ptr(keyring_ref);
possessed = is_key_possessed(keyring_ref);
@@ -380,7 +380,9 @@ descend:
goto not_this_keyring;
/* iterate through the keys in this keyring first */
- for (kix = 0; kix < keylist->nkeys; kix++) {
+ nkeys = keylist->nkeys;
+ smp_rmb();
+ for (kix = 0; kix < nkeys; kix++) {
key = keylist->keys[kix];
kflags = key->flags;
@@ -421,7 +423,9 @@ descend:
/* search through the keyrings nested in this one */
kix = 0;
ascend:
- for (; kix < keylist->nkeys; kix++) {
+ nkeys = keylist->nkeys;
+ smp_rmb();
+ for (; kix < nkeys; kix++) {
key = keylist->keys[kix];
if (key->type != &key_type_keyring)
continue;
@@ -515,7 +519,7 @@ key_ref_t __keyring_search_one(key_ref_t keyring_ref,
struct keyring_list *klist;
unsigned long possessed;
struct key *keyring, *key;
- int loop;
+ int nkeys, loop;
keyring = key_ref_to_ptr(keyring_ref);
possessed = is_key_possessed(keyring_ref);
@@ -524,7 +528,9 @@ key_ref_t __keyring_search_one(key_ref_t keyring_ref,
klist = rcu_dereference(keyring->payload.subscriptions);
if (klist) {
- for (loop = 0; loop < klist->nkeys; loop++) {
+ nkeys = klist->nkeys;
+ smp_rmb();
+ for (loop = 0; loop < nkeys ; loop++) {
key = klist->keys[loop];
if (key->type == ktype &&
@@ -622,7 +628,7 @@ static int keyring_detect_cycle(struct key *A, struct key *B)
struct keyring_list *keylist;
struct key *subtree, *key;
- int sp, kix, ret;
+ int sp, nkeys, kix, ret;
rcu_read_lock();
@@ -645,7 +651,9 @@ descend:
ascend:
/* iterate through the remaining keys in this keyring */
- for (; kix < keylist->nkeys; kix++) {
+ nkeys = keylist->nkeys;
+ smp_rmb();
+ for (; kix < nkeys; kix++) {
key = keylist->keys[kix];
if (key == A)
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH 2/3] keys: fix trusted/encrypted keys sparse rcu_assign_pointer messages
2012-01-17 20:39 [PATCH 1/3] KEYS: Add missing smp_rmb() primitives to the keyring search code David Howells
@ 2012-01-17 20:39 ` David Howells
2012-01-17 20:40 ` [PATCH 3/3] encrypted-keys: fix rcu and sparse messages David Howells
1 sibling, 0 replies; 3+ messages in thread
From: David Howells @ 2012-01-17 20:39 UTC (permalink / raw)
To: jmorris
Cc: keyrings, linux-security-module, linux-kernel, stable,
Mimi Zohar, David Howells
From: Mimi Zohar <zohar@linux.vnet.ibm.com>
Define rcu_assign_keypointer(), which uses the key payload.rcudata instead
of payload.data, to resolve the CONFIG_SPARSE_RCU_POINTER message:
"incompatible types in comparison expression (different address spaces)"
Replace the rcu_assign_pointer() calls in encrypted/trusted keys with
rcu_assign_keypointer().
Signed-off-by: Mimi Zohar <zohar@us.ibm.com>
Signed-off-by: David Howells <dhowells@redhat.com>
---
include/linux/key.h | 3 +++
security/keys/encrypted-keys/encrypted.c | 4 ++--
security/keys/encrypted-keys/masterkey_trusted.c | 2 ++
security/keys/trusted.c | 4 ++--
4 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/include/linux/key.h b/include/linux/key.h
index 183a6af..bfc014c 100644
--- a/include/linux/key.h
+++ b/include/linux/key.h
@@ -293,6 +293,9 @@ static inline bool key_is_instantiated(const struct key *key)
(rcu_dereference_protected((KEY)->payload.rcudata, \
rwsem_is_locked(&((struct key *)(KEY))->sem)))
+#define rcu_assign_keypointer(KEY, PAYLOAD) \
+ (rcu_assign_pointer((KEY)->payload.rcudata, PAYLOAD))
+
#ifdef CONFIG_SYSCTL
extern ctl_table key_sysctls[];
#endif
diff --git a/security/keys/encrypted-keys/encrypted.c b/security/keys/encrypted-keys/encrypted.c
index 41144f7..d91efb6 100644
--- a/security/keys/encrypted-keys/encrypted.c
+++ b/security/keys/encrypted-keys/encrypted.c
@@ -810,7 +810,7 @@ static int encrypted_instantiate(struct key *key, const void *data,
goto out;
}
- rcu_assign_pointer(key->payload.data, epayload);
+ rcu_assign_keypointer(key, epayload);
out:
kfree(datablob);
return ret;
@@ -874,7 +874,7 @@ static int encrypted_update(struct key *key, const void *data, size_t datalen)
memcpy(new_epayload->payload_data, epayload->payload_data,
epayload->payload_datalen);
- rcu_assign_pointer(key->payload.data, new_epayload);
+ rcu_assign_keypointer(key, new_epayload);
call_rcu(&epayload->rcu, encrypted_rcu_free);
out:
kfree(buf);
diff --git a/security/keys/encrypted-keys/masterkey_trusted.c b/security/keys/encrypted-keys/masterkey_trusted.c
index df87272..8c16c3e 100644
--- a/security/keys/encrypted-keys/masterkey_trusted.c
+++ b/security/keys/encrypted-keys/masterkey_trusted.c
@@ -18,6 +18,8 @@
#include <linux/module.h>
#include <linux/err.h>
#include <keys/trusted-type.h>
+#include <keys/encrypted-type.h>
+#include "encrypted.h"
/*
* request_trusted_key - request the trusted key
diff --git a/security/keys/trusted.c b/security/keys/trusted.c
index 0ed5fdf..2d5d041 100644
--- a/security/keys/trusted.c
+++ b/security/keys/trusted.c
@@ -993,7 +993,7 @@ out:
kfree(datablob);
kfree(options);
if (!ret)
- rcu_assign_pointer(key->payload.data, payload);
+ rcu_assign_keypointer(key, payload);
else
kfree(payload);
return ret;
@@ -1067,7 +1067,7 @@ static int trusted_update(struct key *key, const void *data, size_t datalen)
goto out;
}
}
- rcu_assign_pointer(key->payload.data, new_p);
+ rcu_assign_keypointer(key, new_p);
call_rcu(&p->rcu, trusted_rcu_free);
out:
kfree(datablob);
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH 3/3] encrypted-keys: fix rcu and sparse messages
2012-01-17 20:39 [PATCH 1/3] KEYS: Add missing smp_rmb() primitives to the keyring search code David Howells
2012-01-17 20:39 ` [PATCH 2/3] keys: fix trusted/encrypted keys sparse rcu_assign_pointer messages David Howells
@ 2012-01-17 20:40 ` David Howells
1 sibling, 0 replies; 3+ messages in thread
From: David Howells @ 2012-01-17 20:40 UTC (permalink / raw)
To: jmorris
Cc: keyrings, linux-security-module, linux-kernel, stable,
Mimi Zohar, David Howells
From: Mimi Zohar <zohar@linux.vnet.ibm.com>
Enabling CONFIG_PROVE_RCU and CONFIG_SPARSE_RCU_POINTER resulted in
"suspicious rcu_dereference_check() usage!" and "incompatible types
in comparison expression (different address spaces)" messages.
Access the masterkey directly when holding the rwsem.
Changelog v1:
- Use either rcu_read_lock()/rcu_derefence_key()/rcu_read_unlock()
or remove the unnecessary rcu_derefence() - David Howells
Reported-by: Dmitry Kasatkin <dmitry.kasatkin@intel.com>
Signed-off-by: Mimi Zohar <zohar@us.ibm.com>
Signed-off-by: David Howells <dhowells@redhat.com>
---
security/keys/encrypted-keys/encrypted.c | 2 +-
security/keys/encrypted-keys/masterkey_trusted.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/security/keys/encrypted-keys/encrypted.c b/security/keys/encrypted-keys/encrypted.c
index d91efb6..2d1bb8a 100644
--- a/security/keys/encrypted-keys/encrypted.c
+++ b/security/keys/encrypted-keys/encrypted.c
@@ -314,7 +314,7 @@ static struct key *request_user_key(const char *master_desc, u8 **master_key,
goto error;
down_read(&ukey->sem);
- upayload = rcu_dereference(ukey->payload.data);
+ upayload = ukey->payload.data;
*master_key = upayload->data;
*master_keylen = upayload->datalen;
error:
diff --git a/security/keys/encrypted-keys/masterkey_trusted.c b/security/keys/encrypted-keys/masterkey_trusted.c
index 8c16c3e..013f7e5 100644
--- a/security/keys/encrypted-keys/masterkey_trusted.c
+++ b/security/keys/encrypted-keys/masterkey_trusted.c
@@ -39,7 +39,7 @@ struct key *request_trusted_key(const char *trusted_desc,
goto error;
down_read(&tkey->sem);
- tpayload = rcu_dereference(tkey->payload.data);
+ tpayload = tkey->payload.data;
*master_key = tpayload->key;
*master_keylen = tpayload->key_len;
error:
^ permalink raw reply related [flat|nested] 3+ messages in thread
end of thread, other threads:[~2012-01-17 20:40 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-01-17 20:39 [PATCH 1/3] KEYS: Add missing smp_rmb() primitives to the keyring search code David Howells
2012-01-17 20:39 ` [PATCH 2/3] keys: fix trusted/encrypted keys sparse rcu_assign_pointer messages David Howells
2012-01-17 20:40 ` [PATCH 3/3] encrypted-keys: fix rcu and sparse messages David Howells
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).