提交 f66665c0 编写于 作者: E Eric Biggers 提交者: David Howells

ecryptfs: fix dereference of NULL user_key_payload

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: 237fead6 ("[PATCH] ecryptfs: fs/Makefile and fs/Kconfig")
Reviewed-by: NJames Morris <james.l.morris@oracle.com>
Cc: <stable@vger.kernel.org>    [v2.6.19+]
Cc: Michael Halcrow <mhalcrow@google.com>
Signed-off-by: NEric Biggers <ebiggers@google.com>
Signed-off-by: NDavid Howells <dhowells@redhat.com>
上级 d60b5b78
...@@ -84,11 +84,16 @@ struct ecryptfs_page_crypt_context { ...@@ -84,11 +84,16 @@ struct ecryptfs_page_crypt_context {
static inline struct ecryptfs_auth_tok * static inline struct ecryptfs_auth_tok *
ecryptfs_get_encrypted_key_payload_data(struct key *key) ecryptfs_get_encrypted_key_payload_data(struct key *key)
{ {
if (key->type == &key_type_encrypted) struct encrypted_key_payload *payload;
return (struct ecryptfs_auth_tok *)
(&((struct encrypted_key_payload *)key->payload.data[0])->payload_data); if (key->type != &key_type_encrypted)
else
return NULL; return NULL;
payload = key->payload.data[0];
if (!payload)
return ERR_PTR(-EKEYREVOKED);
return (struct ecryptfs_auth_tok *)payload->payload_data;
} }
static inline struct key *ecryptfs_get_encrypted_key(char *sig) static inline struct key *ecryptfs_get_encrypted_key(char *sig)
...@@ -114,12 +119,17 @@ static inline struct ecryptfs_auth_tok * ...@@ -114,12 +119,17 @@ static inline struct ecryptfs_auth_tok *
ecryptfs_get_key_payload_data(struct key *key) ecryptfs_get_key_payload_data(struct key *key)
{ {
struct ecryptfs_auth_tok *auth_tok; struct ecryptfs_auth_tok *auth_tok;
struct user_key_payload *ukp;
auth_tok = ecryptfs_get_encrypted_key_payload_data(key); auth_tok = ecryptfs_get_encrypted_key_payload_data(key);
if (!auth_tok) if (auth_tok)
return (struct ecryptfs_auth_tok *)user_key_payload_locked(key)->data;
else
return auth_tok; return auth_tok;
ukp = user_key_payload_locked(key);
if (!ukp)
return ERR_PTR(-EKEYREVOKED);
return (struct ecryptfs_auth_tok *)ukp->data;
} }
#define ECRYPTFS_MAX_KEYSET_SIZE 1024 #define ECRYPTFS_MAX_KEYSET_SIZE 1024
......
...@@ -459,7 +459,8 @@ static int ecryptfs_verify_version(u16 version) ...@@ -459,7 +459,8 @@ static int ecryptfs_verify_version(u16 version)
* @auth_tok_key: key containing the authentication token * @auth_tok_key: key containing the authentication token
* @auth_tok: authentication token * @auth_tok: authentication token
* *
* Returns zero on valid auth tok; -EINVAL otherwise * Returns zero on valid auth tok; -EINVAL if the payload is invalid; or
* -EKEYREVOKED if the key was revoked before we acquired its semaphore.
*/ */
static int static int
ecryptfs_verify_auth_tok_from_key(struct key *auth_tok_key, ecryptfs_verify_auth_tok_from_key(struct key *auth_tok_key,
...@@ -468,6 +469,12 @@ ecryptfs_verify_auth_tok_from_key(struct key *auth_tok_key, ...@@ -468,6 +469,12 @@ ecryptfs_verify_auth_tok_from_key(struct key *auth_tok_key,
int rc = 0; int rc = 0;
(*auth_tok) = ecryptfs_get_key_payload_data(auth_tok_key); (*auth_tok) = ecryptfs_get_key_payload_data(auth_tok_key);
if (IS_ERR(*auth_tok)) {
rc = PTR_ERR(*auth_tok);
*auth_tok = NULL;
goto out;
}
if (ecryptfs_verify_version((*auth_tok)->version)) { if (ecryptfs_verify_version((*auth_tok)->version)) {
printk(KERN_ERR "Data structure version mismatch. Userspace " printk(KERN_ERR "Data structure version mismatch. Userspace "
"tools must match eCryptfs kernel module with major " "tools must match eCryptfs kernel module with major "
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册