KEYS: user_defined: sanitize key payloads
authorEric Biggers <ebiggers@google.com>
Thu, 8 Jun 2017 13:49:04 +0000 (14:49 +0100)
committerJames Morris <james.l.morris@oracle.com>
Fri, 9 Jun 2017 03:29:48 +0000 (13:29 +1000)
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>
security/keys/user_defined.c

index 26605134f17a8a3cf7c7a5c0a0c14fd5a3052fcb..3d8c68eba5160286fa7af79c8da1ead6e6b05236 100644 (file)
@@ -86,10 +86,18 @@ EXPORT_SYMBOL_GPL(user_preparse);
  */
 void user_free_preparse(struct key_preparsed_payload *prep)
 {
-       kfree(prep->payload.data[0]);
+       kzfree(prep->payload.data[0]);
 }
 EXPORT_SYMBOL_GPL(user_free_preparse);
 
+static void user_free_payload_rcu(struct rcu_head *head)
+{
+       struct user_key_payload *payload;
+
+       payload = container_of(head, struct user_key_payload, rcu);
+       kzfree(payload);
+}
+
 /*
  * update a user defined key
  * - the key's semaphore is write-locked
@@ -112,7 +120,7 @@ int user_update(struct key *key, struct key_preparsed_payload *prep)
        prep->payload.data[0] = NULL;
 
        if (zap)
-               kfree_rcu(zap, rcu);
+               call_rcu(&zap->rcu, user_free_payload_rcu);
        return ret;
 }
 EXPORT_SYMBOL_GPL(user_update);
@@ -130,7 +138,7 @@ void user_revoke(struct key *key)
 
        if (upayload) {
                rcu_assign_keypointer(key, NULL);
-               kfree_rcu(upayload, rcu);
+               call_rcu(&upayload->rcu, user_free_payload_rcu);
        }
 }
 
@@ -143,7 +151,7 @@ void user_destroy(struct key *key)
 {
        struct user_key_payload *upayload = key->payload.data[0];
 
-       kfree(upayload);
+       kzfree(upayload);
 }
 
 EXPORT_SYMBOL_GPL(user_destroy);