fscrypt: add the test dummy encryption key on-demand
When the key for an inode is not found but the inode is using the test_dummy_encryption policy, automatically add the test_dummy_encryption key to the filesystem keyring. This eliminates the need for all the individual filesystems to do this at mount time, which is a bit tricky to clean up from on failure. Note: this covers the call to fscrypt_find_master_key() from inode key setup, but not from the fscrypt ioctls. So, this isn't *exactly* the same as the key being present from the very beginning. I think we can tolerate that, though, since the inode key setup caller is the only one that actually matters in the context of test_dummy_encryption. Signed-off-by: Eric Biggers <ebiggers@google.com> Link: https://lore.kernel.org/r/20230208062107.199831-2-ebiggers@kernel.org
This commit is contained in:
parent
dfb367f897
commit
8dfe6c3f6f
@ -651,6 +651,7 @@ bool fscrypt_policies_equal(const union fscrypt_policy *policy1,
|
||||
const union fscrypt_policy *policy2);
|
||||
int fscrypt_policy_to_key_spec(const union fscrypt_policy *policy,
|
||||
struct fscrypt_key_specifier *key_spec);
|
||||
const union fscrypt_policy *fscrypt_get_dummy_policy(struct super_block *sb);
|
||||
bool fscrypt_supported_policy(const union fscrypt_policy *policy_u,
|
||||
const struct inode *inode);
|
||||
int fscrypt_policy_from_context(union fscrypt_policy *policy_u,
|
||||
|
@ -438,6 +438,7 @@ static int setup_file_encryption_key(struct fscrypt_info *ci,
|
||||
bool need_dirhash_key,
|
||||
struct fscrypt_master_key **mk_ret)
|
||||
{
|
||||
struct super_block *sb = ci->ci_inode->i_sb;
|
||||
struct fscrypt_key_specifier mk_spec;
|
||||
struct fscrypt_master_key *mk;
|
||||
int err;
|
||||
@ -450,8 +451,28 @@ static int setup_file_encryption_key(struct fscrypt_info *ci,
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
mk = fscrypt_find_master_key(ci->ci_inode->i_sb, &mk_spec);
|
||||
if (!mk) {
|
||||
mk = fscrypt_find_master_key(sb, &mk_spec);
|
||||
if (unlikely(!mk)) {
|
||||
const union fscrypt_policy *dummy_policy =
|
||||
fscrypt_get_dummy_policy(sb);
|
||||
|
||||
/*
|
||||
* Add the test_dummy_encryption key on-demand. In principle,
|
||||
* it should be added at mount time. Do it here instead so that
|
||||
* the individual filesystems don't need to worry about adding
|
||||
* this key at mount time and cleaning up on mount failure.
|
||||
*/
|
||||
if (dummy_policy &&
|
||||
fscrypt_policies_equal(dummy_policy, &ci->ci_policy)) {
|
||||
struct fscrypt_dummy_policy tmp = { dummy_policy };
|
||||
|
||||
err = fscrypt_add_test_dummy_key(sb, &tmp);
|
||||
if (err)
|
||||
return err;
|
||||
mk = fscrypt_find_master_key(sb, &mk_spec);
|
||||
}
|
||||
}
|
||||
if (unlikely(!mk)) {
|
||||
if (ci->ci_policy.version != FSCRYPT_POLICY_V1)
|
||||
return -ENOKEY;
|
||||
|
||||
|
@ -53,8 +53,7 @@ int fscrypt_policy_to_key_spec(const union fscrypt_policy *policy,
|
||||
}
|
||||
}
|
||||
|
||||
static const union fscrypt_policy *
|
||||
fscrypt_get_dummy_policy(struct super_block *sb)
|
||||
const union fscrypt_policy *fscrypt_get_dummy_policy(struct super_block *sb)
|
||||
{
|
||||
if (!sb->s_cop->get_dummy_policy)
|
||||
return NULL;
|
||||
|
Loading…
Reference in New Issue
Block a user