| From 13923d0865ca96312197962522e88bc0aedccd74 Mon Sep 17 00:00:00 2001 |
| From: Eric Biggers <ebiggers@google.com> |
| Date: Mon, 9 Oct 2017 12:37:49 -0700 |
| Subject: KEYS: encrypted: fix dereference of NULL user_key_payload |
| |
| From: Eric Biggers <ebiggers@google.com> |
| |
| commit 13923d0865ca96312197962522e88bc0aedccd74 upstream. |
| |
| A key of type "encrypted" references a "master key" which is used to |
| encrypt and decrypt the encrypted key's payload. However, when we |
| accessed the master key's payload, we failed to handle the case where |
| the master key has been revoked, which sets the payload pointer to NULL. |
| Note that request_key() *does* skip revoked keys, but there is still a |
| window where the key can be revoked before we acquire its semaphore. |
| |
| Fix it by checking for a NULL payload, treating it like a key which was |
| already revoked at the time it was requested. |
| |
| This was an issue for master keys of type "user" only. Master keys can |
| also be of type "trusted", but those cannot be revoked. |
| |
| Fixes: 7e70cb497850 ("keys: add new key-type encrypted") |
| Reviewed-by: James Morris <james.l.morris@oracle.com> |
| Cc: Mimi Zohar <zohar@linux.vnet.ibm.com> |
| Cc: David Safford <safford@us.ibm.com> |
| Signed-off-by: Eric Biggers <ebiggers@google.com> |
| Signed-off-by: David Howells <dhowells@redhat.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| |
| --- |
| security/keys/encrypted-keys/encrypted.c | 7 +++++++ |
| 1 file changed, 7 insertions(+) |
| |
| --- a/security/keys/encrypted-keys/encrypted.c |
| +++ b/security/keys/encrypted-keys/encrypted.c |
| @@ -315,6 +315,13 @@ static struct key *request_user_key(cons |
| |
| down_read(&ukey->sem); |
| upayload = ukey->payload.data; |
| + if (!upayload) { |
| + /* key was revoked before we acquired its semaphore */ |
| + up_read(&ukey->sem); |
| + key_put(ukey); |
| + ukey = ERR_PTR(-EKEYREVOKED); |
| + goto error; |
| + } |
| *master_key = upayload->data; |
| *master_keylen = upayload->datalen; |
| error: |