Skip to content

Commit 50044e4

Browse files
ebiggersgregkh
authored andcommitted
ecryptfs: fix dereference of NULL user_key_payload
commit f66665c09ab489a11ca490d6a82df57cfc1bea3e upstream. In eCryptfs, we failed to verify that the authentication token keys are not revoked before dereferencing their payloads, which is problematic because the payload of a revoked key is NULL. request_key() *does* skip revoked keys, but there is still a window where the key can be revoked before we acquire the key semaphore. Fix it by updating ecryptfs_get_key_payload_data() to return -EKEYREVOKED if the key payload is NULL. For completeness we check this for "encrypted" keys as well as "user" keys, although encrypted keys cannot be revoked currently. Alternatively we could use key_validate(), but since we'll also need to fix ecryptfs_get_key_payload_data() to validate the payload length, it seems appropriate to just check the payload pointer. Fixes: 237fead ("[PATCH] ecryptfs: fs/Makefile and fs/Kconfig") Reviewed-by: James Morris <james.l.morris@oracle.com> Cc: Michael Halcrow <mhalcrow@google.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>
1 parent da0933c commit 50044e4

2 files changed

Lines changed: 25 additions & 8 deletions

File tree

fs/ecryptfs/ecryptfs_kernel.h

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -84,11 +84,16 @@ struct ecryptfs_page_crypt_context {
8484
static inline struct ecryptfs_auth_tok *
8585
ecryptfs_get_encrypted_key_payload_data(struct key *key)
8686
{
87-
if (key->type == &key_type_encrypted)
88-
return (struct ecryptfs_auth_tok *)
89-
(&((struct encrypted_key_payload *)key->payload.data[0])->payload_data);
90-
else
87+
struct encrypted_key_payload *payload;
88+
89+
if (key->type != &key_type_encrypted)
9190
return NULL;
91+
92+
payload = key->payload.data[0];
93+
if (!payload)
94+
return ERR_PTR(-EKEYREVOKED);
95+
96+
return (struct ecryptfs_auth_tok *)payload->payload_data;
9297
}
9398

9499
static inline struct key *ecryptfs_get_encrypted_key(char *sig)
@@ -114,12 +119,17 @@ static inline struct ecryptfs_auth_tok *
114119
ecryptfs_get_key_payload_data(struct key *key)
115120
{
116121
struct ecryptfs_auth_tok *auth_tok;
122+
const struct user_key_payload *ukp;
117123

118124
auth_tok = ecryptfs_get_encrypted_key_payload_data(key);
119-
if (!auth_tok)
120-
return (struct ecryptfs_auth_tok *)user_key_payload(key)->data;
121-
else
125+
if (auth_tok)
122126
return auth_tok;
127+
128+
ukp = user_key_payload(key);
129+
if (!ukp)
130+
return ERR_PTR(-EKEYREVOKED);
131+
132+
return (struct ecryptfs_auth_tok *)ukp->data;
123133
}
124134

125135
#define ECRYPTFS_MAX_KEYSET_SIZE 1024

fs/ecryptfs/keystore.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -458,7 +458,8 @@ static int ecryptfs_verify_version(u16 version)
458458
* @auth_tok_key: key containing the authentication token
459459
* @auth_tok: authentication token
460460
*
461-
* Returns zero on valid auth tok; -EINVAL otherwise
461+
* Returns zero on valid auth tok; -EINVAL if the payload is invalid; or
462+
* -EKEYREVOKED if the key was revoked before we acquired its semaphore.
462463
*/
463464
static int
464465
ecryptfs_verify_auth_tok_from_key(struct key *auth_tok_key,
@@ -467,6 +468,12 @@ ecryptfs_verify_auth_tok_from_key(struct key *auth_tok_key,
467468
int rc = 0;
468469

469470
(*auth_tok) = ecryptfs_get_key_payload_data(auth_tok_key);
471+
if (IS_ERR(*auth_tok)) {
472+
rc = PTR_ERR(*auth_tok);
473+
*auth_tok = NULL;
474+
goto out;
475+
}
476+
470477
if (ecryptfs_verify_version((*auth_tok)->version)) {
471478
printk(KERN_ERR "Data structure version mismatch. Userspace "
472479
"tools must match eCryptfs kernel module with major "

0 commit comments

Comments
 (0)