fscrypt: don't allow v1 policies with casefolding
Casefolded encrypted directories will use a new dirhash method that requires a secret key. If the directory uses a v2 encryption policy, it's easy to derive this key from the master key using HKDF. However, v1 encryption policies don't provide a way to derive additional keys. Therefore, don't allow casefolding on directories that use a v1 policy. Specifically, make it so that trying to enable casefolding on a directory that has a v1 policy fails, trying to set a v1 policy on a casefolded directory fails, and trying to open a casefolded directory that has a v1 policy (if one somehow exists on-disk) fails. Signed-off-by: Daniel Rosenberg <drosen@google.com> [EB: improved commit message, updated fscrypt.rst, and other cleanups] Link: https://lore.kernel.org/r/20200120223201.241390-2-ebiggers@kernel.org Signed-off-by: Eric Biggers <ebiggers@google.com>
This commit is contained in:

committed by
Eric Biggers

parent
1b3b827ee5
commit
6e1918cfb2
@@ -122,6 +122,34 @@ int __fscrypt_prepare_lookup(struct inode *dir, struct dentry *dentry,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(__fscrypt_prepare_lookup);
|
||||
|
||||
/**
|
||||
* fscrypt_prepare_setflags() - prepare to change flags with FS_IOC_SETFLAGS
|
||||
* @inode: the inode on which flags are being changed
|
||||
* @oldflags: the old flags
|
||||
* @flags: the new flags
|
||||
*
|
||||
* The caller should be holding i_rwsem for write.
|
||||
*
|
||||
* Return: 0 on success; -errno if the flags change isn't allowed or if
|
||||
* another error occurs.
|
||||
*/
|
||||
int fscrypt_prepare_setflags(struct inode *inode,
|
||||
unsigned int oldflags, unsigned int flags)
|
||||
{
|
||||
struct fscrypt_info *ci;
|
||||
int err;
|
||||
|
||||
if (IS_ENCRYPTED(inode) && (flags & ~oldflags & FS_CASEFOLD_FL)) {
|
||||
err = fscrypt_require_key(inode);
|
||||
if (err)
|
||||
return err;
|
||||
ci = inode->i_crypt_info;
|
||||
if (ci->ci_policy.version != FSCRYPT_POLICY_V2)
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __fscrypt_prepare_symlink(struct inode *dir, unsigned int len,
|
||||
unsigned int max_len,
|
||||
struct fscrypt_str *disk_link)
|
||||
|
@@ -124,6 +124,13 @@ static bool fscrypt_supported_v1_policy(const struct fscrypt_policy_v1 *policy,
|
||||
policy->filenames_encryption_mode))
|
||||
return false;
|
||||
|
||||
if (IS_CASEFOLDED(inode)) {
|
||||
/* With v1, there's no way to derive dirhash keys. */
|
||||
fscrypt_warn(inode,
|
||||
"v1 policies can't be used on casefolded directories");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user