A code cleanup and bugfix for fs/crypto.
-----BEGIN PGP SIGNATURE----- iQEzBAABCAAdFiEEK2m5VNv+CHkogTfJ8vlZVpUNgaMFAljW4wYACgkQ8vlZVpUN gaPYugf9ExFbJhN+iYqUVbGXPvlr5VpEtDeVt7IfO3a37hqCEQ0IEPzksNIfUFul B8/rYXpz0B5gqCJeo66CGLkb1SVvSoSKCq9/BTQtugohxM7sGxDFTmdB+A+u0QJH leILfaMFuj0DhVOrdYVpGh7e1XPgSTUWy6/G42OJqf3SV2WxGRJtyBfmghZxEdiY XYCGqjq47yOIPvzB+ufKe1hnphKMgxlHeuPvByzPCvOs58GlxAYR3Ycuvjc/nz+8 QVlAEPpGhf9ytEXELsxq/ZbsNj9xtXsNAzkAoMK+xZ2JCxIHRcS1ay/iAwxw+d9r bnlpI+8tQ79GIGCv3cusJSwq7j1iuQ== =wPlW -----END PGP SIGNATURE----- Merge tag 'fscrypt-for-linus_stable' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/fscrypt Pull fscrypto fixes from Ted Ts'o: "A code cleanup and bugfix for fs/crypto" * tag 'fscrypt-for-linus_stable' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/fscrypt: fscrypt: eliminate ->prepare_context() operation fscrypt: remove broken support for detecting keyring key revocation
This commit is contained in:
Коммит
a643f9054c
|
@ -327,7 +327,6 @@ EXPORT_SYMBOL(fscrypt_decrypt_page);
|
||||||
static int fscrypt_d_revalidate(struct dentry *dentry, unsigned int flags)
|
static int fscrypt_d_revalidate(struct dentry *dentry, unsigned int flags)
|
||||||
{
|
{
|
||||||
struct dentry *dir;
|
struct dentry *dir;
|
||||||
struct fscrypt_info *ci;
|
|
||||||
int dir_has_key, cached_with_key;
|
int dir_has_key, cached_with_key;
|
||||||
|
|
||||||
if (flags & LOOKUP_RCU)
|
if (flags & LOOKUP_RCU)
|
||||||
|
@ -339,18 +338,11 @@ static int fscrypt_d_revalidate(struct dentry *dentry, unsigned int flags)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ci = d_inode(dir)->i_crypt_info;
|
|
||||||
if (ci && ci->ci_keyring_key &&
|
|
||||||
(ci->ci_keyring_key->flags & ((1 << KEY_FLAG_INVALIDATED) |
|
|
||||||
(1 << KEY_FLAG_REVOKED) |
|
|
||||||
(1 << KEY_FLAG_DEAD))))
|
|
||||||
ci = NULL;
|
|
||||||
|
|
||||||
/* this should eventually be an flag in d_flags */
|
/* this should eventually be an flag in d_flags */
|
||||||
spin_lock(&dentry->d_lock);
|
spin_lock(&dentry->d_lock);
|
||||||
cached_with_key = dentry->d_flags & DCACHE_ENCRYPTED_WITH_KEY;
|
cached_with_key = dentry->d_flags & DCACHE_ENCRYPTED_WITH_KEY;
|
||||||
spin_unlock(&dentry->d_lock);
|
spin_unlock(&dentry->d_lock);
|
||||||
dir_has_key = (ci != NULL);
|
dir_has_key = (d_inode(dir)->i_crypt_info != NULL);
|
||||||
dput(dir);
|
dput(dir);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -350,7 +350,7 @@ int fscrypt_setup_filename(struct inode *dir, const struct qstr *iname,
|
||||||
fname->disk_name.len = iname->len;
|
fname->disk_name.len = iname->len;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
ret = fscrypt_get_crypt_info(dir);
|
ret = fscrypt_get_encryption_info(dir);
|
||||||
if (ret && ret != -EOPNOTSUPP)
|
if (ret && ret != -EOPNOTSUPP)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
|
|
@ -67,7 +67,6 @@ struct fscrypt_info {
|
||||||
u8 ci_filename_mode;
|
u8 ci_filename_mode;
|
||||||
u8 ci_flags;
|
u8 ci_flags;
|
||||||
struct crypto_skcipher *ci_ctfm;
|
struct crypto_skcipher *ci_ctfm;
|
||||||
struct key *ci_keyring_key;
|
|
||||||
u8 ci_master_key[FS_KEY_DESCRIPTOR_SIZE];
|
u8 ci_master_key[FS_KEY_DESCRIPTOR_SIZE];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -101,7 +100,4 @@ extern int fscrypt_do_page_crypto(const struct inode *inode,
|
||||||
extern struct page *fscrypt_alloc_bounce_page(struct fscrypt_ctx *ctx,
|
extern struct page *fscrypt_alloc_bounce_page(struct fscrypt_ctx *ctx,
|
||||||
gfp_t gfp_flags);
|
gfp_t gfp_flags);
|
||||||
|
|
||||||
/* keyinfo.c */
|
|
||||||
extern int fscrypt_get_crypt_info(struct inode *);
|
|
||||||
|
|
||||||
#endif /* _FSCRYPT_PRIVATE_H */
|
#endif /* _FSCRYPT_PRIVATE_H */
|
||||||
|
|
|
@ -95,6 +95,7 @@ static int validate_user_key(struct fscrypt_info *crypt_info,
|
||||||
kfree(description);
|
kfree(description);
|
||||||
if (IS_ERR(keyring_key))
|
if (IS_ERR(keyring_key))
|
||||||
return PTR_ERR(keyring_key);
|
return PTR_ERR(keyring_key);
|
||||||
|
down_read(&keyring_key->sem);
|
||||||
|
|
||||||
if (keyring_key->type != &key_type_logon) {
|
if (keyring_key->type != &key_type_logon) {
|
||||||
printk_once(KERN_WARNING
|
printk_once(KERN_WARNING
|
||||||
|
@ -102,11 +103,9 @@ static int validate_user_key(struct fscrypt_info *crypt_info,
|
||||||
res = -ENOKEY;
|
res = -ENOKEY;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
down_read(&keyring_key->sem);
|
|
||||||
ukp = user_key_payload_locked(keyring_key);
|
ukp = user_key_payload_locked(keyring_key);
|
||||||
if (ukp->datalen != sizeof(struct fscrypt_key)) {
|
if (ukp->datalen != sizeof(struct fscrypt_key)) {
|
||||||
res = -EINVAL;
|
res = -EINVAL;
|
||||||
up_read(&keyring_key->sem);
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
master_key = (struct fscrypt_key *)ukp->data;
|
master_key = (struct fscrypt_key *)ukp->data;
|
||||||
|
@ -117,17 +116,11 @@ static int validate_user_key(struct fscrypt_info *crypt_info,
|
||||||
"%s: key size incorrect: %d\n",
|
"%s: key size incorrect: %d\n",
|
||||||
__func__, master_key->size);
|
__func__, master_key->size);
|
||||||
res = -ENOKEY;
|
res = -ENOKEY;
|
||||||
up_read(&keyring_key->sem);
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
res = derive_key_aes(ctx->nonce, master_key->raw, raw_key);
|
res = derive_key_aes(ctx->nonce, master_key->raw, raw_key);
|
||||||
up_read(&keyring_key->sem);
|
|
||||||
if (res)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
crypt_info->ci_keyring_key = keyring_key;
|
|
||||||
return 0;
|
|
||||||
out:
|
out:
|
||||||
|
up_read(&keyring_key->sem);
|
||||||
key_put(keyring_key);
|
key_put(keyring_key);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -169,12 +162,11 @@ static void put_crypt_info(struct fscrypt_info *ci)
|
||||||
if (!ci)
|
if (!ci)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
key_put(ci->ci_keyring_key);
|
|
||||||
crypto_free_skcipher(ci->ci_ctfm);
|
crypto_free_skcipher(ci->ci_ctfm);
|
||||||
kmem_cache_free(fscrypt_info_cachep, ci);
|
kmem_cache_free(fscrypt_info_cachep, ci);
|
||||||
}
|
}
|
||||||
|
|
||||||
int fscrypt_get_crypt_info(struct inode *inode)
|
int fscrypt_get_encryption_info(struct inode *inode)
|
||||||
{
|
{
|
||||||
struct fscrypt_info *crypt_info;
|
struct fscrypt_info *crypt_info;
|
||||||
struct fscrypt_context ctx;
|
struct fscrypt_context ctx;
|
||||||
|
@ -184,21 +176,15 @@ int fscrypt_get_crypt_info(struct inode *inode)
|
||||||
u8 *raw_key = NULL;
|
u8 *raw_key = NULL;
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
|
if (inode->i_crypt_info)
|
||||||
|
return 0;
|
||||||
|
|
||||||
res = fscrypt_initialize(inode->i_sb->s_cop->flags);
|
res = fscrypt_initialize(inode->i_sb->s_cop->flags);
|
||||||
if (res)
|
if (res)
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
if (!inode->i_sb->s_cop->get_context)
|
if (!inode->i_sb->s_cop->get_context)
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
retry:
|
|
||||||
crypt_info = ACCESS_ONCE(inode->i_crypt_info);
|
|
||||||
if (crypt_info) {
|
|
||||||
if (!crypt_info->ci_keyring_key ||
|
|
||||||
key_validate(crypt_info->ci_keyring_key) == 0)
|
|
||||||
return 0;
|
|
||||||
fscrypt_put_encryption_info(inode, crypt_info);
|
|
||||||
goto retry;
|
|
||||||
}
|
|
||||||
|
|
||||||
res = inode->i_sb->s_cop->get_context(inode, &ctx, sizeof(ctx));
|
res = inode->i_sb->s_cop->get_context(inode, &ctx, sizeof(ctx));
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
|
@ -229,7 +215,6 @@ retry:
|
||||||
crypt_info->ci_data_mode = ctx.contents_encryption_mode;
|
crypt_info->ci_data_mode = ctx.contents_encryption_mode;
|
||||||
crypt_info->ci_filename_mode = ctx.filenames_encryption_mode;
|
crypt_info->ci_filename_mode = ctx.filenames_encryption_mode;
|
||||||
crypt_info->ci_ctfm = NULL;
|
crypt_info->ci_ctfm = NULL;
|
||||||
crypt_info->ci_keyring_key = NULL;
|
|
||||||
memcpy(crypt_info->ci_master_key, ctx.master_key_descriptor,
|
memcpy(crypt_info->ci_master_key, ctx.master_key_descriptor,
|
||||||
sizeof(crypt_info->ci_master_key));
|
sizeof(crypt_info->ci_master_key));
|
||||||
|
|
||||||
|
@ -273,14 +258,8 @@ retry:
|
||||||
if (res)
|
if (res)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
kzfree(raw_key);
|
if (cmpxchg(&inode->i_crypt_info, NULL, crypt_info) == NULL)
|
||||||
raw_key = NULL;
|
crypt_info = NULL;
|
||||||
if (cmpxchg(&inode->i_crypt_info, NULL, crypt_info) != NULL) {
|
|
||||||
put_crypt_info(crypt_info);
|
|
||||||
goto retry;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (res == -ENOKEY)
|
if (res == -ENOKEY)
|
||||||
res = 0;
|
res = 0;
|
||||||
|
@ -288,6 +267,7 @@ out:
|
||||||
kzfree(raw_key);
|
kzfree(raw_key);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(fscrypt_get_encryption_info);
|
||||||
|
|
||||||
void fscrypt_put_encryption_info(struct inode *inode, struct fscrypt_info *ci)
|
void fscrypt_put_encryption_info(struct inode *inode, struct fscrypt_info *ci)
|
||||||
{
|
{
|
||||||
|
@ -305,17 +285,3 @@ void fscrypt_put_encryption_info(struct inode *inode, struct fscrypt_info *ci)
|
||||||
put_crypt_info(ci);
|
put_crypt_info(ci);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(fscrypt_put_encryption_info);
|
EXPORT_SYMBOL(fscrypt_put_encryption_info);
|
||||||
|
|
||||||
int fscrypt_get_encryption_info(struct inode *inode)
|
|
||||||
{
|
|
||||||
struct fscrypt_info *ci = inode->i_crypt_info;
|
|
||||||
|
|
||||||
if (!ci ||
|
|
||||||
(ci->ci_keyring_key &&
|
|
||||||
(ci->ci_keyring_key->flags & ((1 << KEY_FLAG_INVALIDATED) |
|
|
||||||
(1 << KEY_FLAG_REVOKED) |
|
|
||||||
(1 << KEY_FLAG_DEAD)))))
|
|
||||||
return fscrypt_get_crypt_info(inode);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(fscrypt_get_encryption_info);
|
|
||||||
|
|
|
@ -33,17 +33,10 @@ static int create_encryption_context_from_policy(struct inode *inode,
|
||||||
const struct fscrypt_policy *policy)
|
const struct fscrypt_policy *policy)
|
||||||
{
|
{
|
||||||
struct fscrypt_context ctx;
|
struct fscrypt_context ctx;
|
||||||
int res;
|
|
||||||
|
|
||||||
if (!inode->i_sb->s_cop->set_context)
|
if (!inode->i_sb->s_cop->set_context)
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
if (inode->i_sb->s_cop->prepare_context) {
|
|
||||||
res = inode->i_sb->s_cop->prepare_context(inode);
|
|
||||||
if (res)
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx.format = FS_ENCRYPTION_CONTEXT_FORMAT_V1;
|
ctx.format = FS_ENCRYPTION_CONTEXT_FORMAT_V1;
|
||||||
memcpy(ctx.master_key_descriptor, policy->master_key_descriptor,
|
memcpy(ctx.master_key_descriptor, policy->master_key_descriptor,
|
||||||
FS_KEY_DESCRIPTOR_SIZE);
|
FS_KEY_DESCRIPTOR_SIZE);
|
||||||
|
|
|
@ -1120,17 +1120,16 @@ static int ext4_get_context(struct inode *inode, void *ctx, size_t len)
|
||||||
EXT4_XATTR_NAME_ENCRYPTION_CONTEXT, ctx, len);
|
EXT4_XATTR_NAME_ENCRYPTION_CONTEXT, ctx, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ext4_prepare_context(struct inode *inode)
|
|
||||||
{
|
|
||||||
return ext4_convert_inline_data(inode);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int ext4_set_context(struct inode *inode, const void *ctx, size_t len,
|
static int ext4_set_context(struct inode *inode, const void *ctx, size_t len,
|
||||||
void *fs_data)
|
void *fs_data)
|
||||||
{
|
{
|
||||||
handle_t *handle = fs_data;
|
handle_t *handle = fs_data;
|
||||||
int res, res2, retries = 0;
|
int res, res2, retries = 0;
|
||||||
|
|
||||||
|
res = ext4_convert_inline_data(inode);
|
||||||
|
if (res)
|
||||||
|
return res;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If a journal handle was specified, then the encryption context is
|
* If a journal handle was specified, then the encryption context is
|
||||||
* being set on a new inode via inheritance and is part of a larger
|
* being set on a new inode via inheritance and is part of a larger
|
||||||
|
@ -1196,7 +1195,6 @@ static unsigned ext4_max_namelen(struct inode *inode)
|
||||||
static const struct fscrypt_operations ext4_cryptops = {
|
static const struct fscrypt_operations ext4_cryptops = {
|
||||||
.key_prefix = "ext4:",
|
.key_prefix = "ext4:",
|
||||||
.get_context = ext4_get_context,
|
.get_context = ext4_get_context,
|
||||||
.prepare_context = ext4_prepare_context,
|
|
||||||
.set_context = ext4_set_context,
|
.set_context = ext4_set_context,
|
||||||
.dummy_context = ext4_dummy_context,
|
.dummy_context = ext4_dummy_context,
|
||||||
.is_encrypted = ext4_encrypted_inode,
|
.is_encrypted = ext4_encrypted_inode,
|
||||||
|
|
|
@ -87,7 +87,6 @@ struct fscrypt_operations {
|
||||||
unsigned int flags;
|
unsigned int flags;
|
||||||
const char *key_prefix;
|
const char *key_prefix;
|
||||||
int (*get_context)(struct inode *, void *, size_t);
|
int (*get_context)(struct inode *, void *, size_t);
|
||||||
int (*prepare_context)(struct inode *);
|
|
||||||
int (*set_context)(struct inode *, const void *, size_t, void *);
|
int (*set_context)(struct inode *, const void *, size_t, void *);
|
||||||
int (*dummy_context)(struct inode *);
|
int (*dummy_context)(struct inode *);
|
||||||
bool (*is_encrypted)(struct inode *);
|
bool (*is_encrypted)(struct inode *);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче