summaryrefslogtreecommitdiffstats
path: root/security/keys
diff options
context:
space:
mode:
authorEric Biggers <ebiggers@google.com>2017-06-08 09:49:04 -0400
committerJames Morris <james.l.morris@oracle.com>2017-06-08 23:29:48 -0400
commit6966c74932b328b3d6df92b11b083bfbcd067986 (patch)
tree0ce4998b3543b9dbbf884a929b580dc3bb698443 /security/keys
parent57070c850a03ee0cea654fc22cb8032fc3139d39 (diff)
KEYS: user_defined: sanitize key payloads
Zero the payloads of user and logon keys before freeing them. This prevents sensitive key material from being kept around in the slab caches after a key is released. Signed-off-by: Eric Biggers <ebiggers@google.com> Signed-off-by: David Howells <dhowells@redhat.com> Signed-off-by: James Morris <james.l.morris@oracle.com>
Diffstat (limited to 'security/keys')
-rw-r--r--security/keys/user_defined.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/security/keys/user_defined.c b/security/keys/user_defined.c
index 26605134f17a..3d8c68eba516 100644
--- a/security/keys/user_defined.c
+++ b/security/keys/user_defined.c
@@ -86,10 +86,18 @@ EXPORT_SYMBOL_GPL(user_preparse);
86 */ 86 */
87void user_free_preparse(struct key_preparsed_payload *prep) 87void user_free_preparse(struct key_preparsed_payload *prep)
88{ 88{
89 kfree(prep->payload.data[0]); 89 kzfree(prep->payload.data[0]);
90} 90}
91EXPORT_SYMBOL_GPL(user_free_preparse); 91EXPORT_SYMBOL_GPL(user_free_preparse);
92 92
93static void user_free_payload_rcu(struct rcu_head *head)
94{
95 struct user_key_payload *payload;
96
97 payload = container_of(head, struct user_key_payload, rcu);
98 kzfree(payload);
99}
100
93/* 101/*
94 * update a user defined key 102 * update a user defined key
95 * - the key's semaphore is write-locked 103 * - the key's semaphore is write-locked
@@ -112,7 +120,7 @@ int user_update(struct key *key, struct key_preparsed_payload *prep)
112 prep->payload.data[0] = NULL; 120 prep->payload.data[0] = NULL;
113 121
114 if (zap) 122 if (zap)
115 kfree_rcu(zap, rcu); 123 call_rcu(&zap->rcu, user_free_payload_rcu);
116 return ret; 124 return ret;
117} 125}
118EXPORT_SYMBOL_GPL(user_update); 126EXPORT_SYMBOL_GPL(user_update);
@@ -130,7 +138,7 @@ void user_revoke(struct key *key)
130 138
131 if (upayload) { 139 if (upayload) {
132 rcu_assign_keypointer(key, NULL); 140 rcu_assign_keypointer(key, NULL);
133 kfree_rcu(upayload, rcu); 141 call_rcu(&upayload->rcu, user_free_payload_rcu);
134 } 142 }
135} 143}
136 144
@@ -143,7 +151,7 @@ void user_destroy(struct key *key)
143{ 151{
144 struct user_key_payload *upayload = key->payload.data[0]; 152 struct user_key_payload *upayload = key->payload.data[0];
145 153
146 kfree(upayload); 154 kzfree(upayload);
147} 155}
148 156
149EXPORT_SYMBOL_GPL(user_destroy); 157EXPORT_SYMBOL_GPL(user_destroy);