Merge branch 'fixes-v4.14-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security
Pull key handling fixes from James Morris:
"This includes a fix for the capabilities code from Colin King, and a
set of further fixes for the keys subsystem. From David:
- Fix a bunch of places where kernel drivers may access revoked
user-type keys and don't do it correctly.
- Fix some ecryptfs bits.
- Fix big_key to require CONFIG_CRYPTO.
- Fix a couple of bugs in the asymmetric key type.
- Fix a race between updating and finding negative keys.
- Prevent add_key() from updating uninstantiated keys.
- Make loading of key flags and expiry time atomic when not holding
locks"
* 'fixes-v4.14-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security:
commoncap: move assignment of fs_ns to avoid null pointer dereference
pkcs7: Prevent NULL pointer dereference, since sinfo is not always set.
KEYS: load key flags and expiry time atomically in proc_keys_show()
KEYS: Load key expiry time atomically in keyring_search_iterator()
KEYS: load key flags and expiry time atomically in key_validate()
KEYS: don't let add_key() update an uninstantiated key
KEYS: Fix race between updating and finding a negative key
KEYS: checking the input id parameters before finding asymmetric key
KEYS: Fix the wrong index when checking the existence of second id
security/keys: BIG_KEY requires CONFIG_CRYPTO
ecryptfs: fix dereference of NULL user_key_payload
fscrypt: fix dereference of NULL user_key_payload
lib/digsig: fix dereference of NULL user_key_payload
FS-Cache: fix dereference of NULL user_key_payload
KEYS: encrypted: fix dereference of NULL user_key_payload
This commit is contained in:
@@ -109,6 +109,11 @@ static int validate_user_key(struct fscrypt_info *crypt_info,
|
||||
goto out;
|
||||
}
|
||||
ukp = user_key_payload_locked(keyring_key);
|
||||
if (!ukp) {
|
||||
/* key was revoked before we acquired its semaphore */
|
||||
res = -EKEYREVOKED;
|
||||
goto out;
|
||||
}
|
||||
if (ukp->datalen != sizeof(struct fscrypt_key)) {
|
||||
res = -EINVAL;
|
||||
goto out;
|
||||
|
||||
@@ -84,11 +84,16 @@ struct ecryptfs_page_crypt_context {
|
||||
static inline struct ecryptfs_auth_tok *
|
||||
ecryptfs_get_encrypted_key_payload_data(struct key *key)
|
||||
{
|
||||
if (key->type == &key_type_encrypted)
|
||||
return (struct ecryptfs_auth_tok *)
|
||||
(&((struct encrypted_key_payload *)key->payload.data[0])->payload_data);
|
||||
else
|
||||
struct encrypted_key_payload *payload;
|
||||
|
||||
if (key->type != &key_type_encrypted)
|
||||
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)
|
||||
@@ -114,12 +119,17 @@ static inline struct ecryptfs_auth_tok *
|
||||
ecryptfs_get_key_payload_data(struct key *key)
|
||||
{
|
||||
struct ecryptfs_auth_tok *auth_tok;
|
||||
struct user_key_payload *ukp;
|
||||
|
||||
auth_tok = ecryptfs_get_encrypted_key_payload_data(key);
|
||||
if (!auth_tok)
|
||||
return (struct ecryptfs_auth_tok *)user_key_payload_locked(key)->data;
|
||||
else
|
||||
if (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
|
||||
|
||||
@@ -459,7 +459,8 @@ out:
|
||||
* @auth_tok_key: key containing the 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
|
||||
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;
|
||||
|
||||
(*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)) {
|
||||
printk(KERN_ERR "Data structure version mismatch. Userspace "
|
||||
"tools must match eCryptfs kernel module with major "
|
||||
|
||||
@@ -331,6 +331,13 @@ static void fscache_objlist_config(struct fscache_objlist_data *data)
|
||||
rcu_read_lock();
|
||||
|
||||
confkey = user_key_payload_rcu(key);
|
||||
if (!confkey) {
|
||||
/* key was revoked */
|
||||
rcu_read_unlock();
|
||||
key_put(key);
|
||||
goto no_config;
|
||||
}
|
||||
|
||||
buf = confkey->data;
|
||||
|
||||
for (len = confkey->datalen - 1; len >= 0; len--) {
|
||||
|
||||
Reference in New Issue
Block a user