diff options
author | Eric Biggers <ebiggers@google.com> | 2017-06-08 09:49:04 -0400 |
---|---|---|
committer | James Morris <james.l.morris@oracle.com> | 2017-06-08 23:29:48 -0400 |
commit | 6966c74932b328b3d6df92b11b083bfbcd067986 (patch) | |
tree | 0ce4998b3543b9dbbf884a929b580dc3bb698443 /security/keys | |
parent | 57070c850a03ee0cea654fc22cb8032fc3139d39 (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.c | 16 |
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 | */ |
87 | void user_free_preparse(struct key_preparsed_payload *prep) | 87 | void user_free_preparse(struct key_preparsed_payload *prep) |
88 | { | 88 | { |
89 | kfree(prep->payload.data[0]); | 89 | kzfree(prep->payload.data[0]); |
90 | } | 90 | } |
91 | EXPORT_SYMBOL_GPL(user_free_preparse); | 91 | EXPORT_SYMBOL_GPL(user_free_preparse); |
92 | 92 | ||
93 | static 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 | } |
118 | EXPORT_SYMBOL_GPL(user_update); | 126 | EXPORT_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 | ||
149 | EXPORT_SYMBOL_GPL(user_destroy); | 157 | EXPORT_SYMBOL_GPL(user_destroy); |