summaryrefslogtreecommitdiff
path: root/fs/crypto/inline_crypt.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/crypto/inline_crypt.c')
-rw-r--r--fs/crypto/inline_crypt.c57
1 files changed, 20 insertions, 37 deletions
diff --git a/fs/crypto/inline_crypt.c b/fs/crypto/inline_crypt.c
index 47324062fee5..66b9c9150fed 100644
--- a/fs/crypto/inline_crypt.c
+++ b/fs/crypto/inline_crypt.c
@@ -22,22 +22,14 @@
#include "fscrypt_private.h"
-static struct block_device **fscrypt_get_devices(struct super_block *sb,
- unsigned int *num_devs)
+static unsigned int
+fscrypt_get_devices(struct super_block *sb,
+ struct block_device *devs[FSCRYPT_MAX_DEVICES])
{
- struct block_device **devs;
-
- if (sb->s_cop->get_devices) {
- devs = sb->s_cop->get_devices(sb, num_devs);
- if (devs)
- return devs;
- }
- devs = kmalloc_obj(*devs);
- if (!devs)
- return ERR_PTR(-ENOMEM);
+ if (sb->s_cop->get_devices)
+ return sb->s_cop->get_devices(sb, devs);
devs[0] = sb->s_bdev;
- *num_devs = 1;
- return devs;
+ return 1;
}
static unsigned int fscrypt_get_dun_bytes(const struct fscrypt_inode_info *ci)
@@ -96,7 +88,7 @@ int fscrypt_select_encryption_impl(struct fscrypt_inode_info *ci,
const struct inode *inode = ci->ci_inode;
struct super_block *sb = inode->i_sb;
struct blk_crypto_config crypto_cfg;
- struct block_device **devs;
+ struct block_device *devs[FSCRYPT_MAX_DEVICES];
unsigned int num_devs;
unsigned int i;
@@ -135,20 +127,15 @@ int fscrypt_select_encryption_impl(struct fscrypt_inode_info *ci,
crypto_cfg.key_type = is_hw_wrapped_key ?
BLK_CRYPTO_KEY_TYPE_HW_WRAPPED : BLK_CRYPTO_KEY_TYPE_RAW;
- devs = fscrypt_get_devices(sb, &num_devs);
- if (IS_ERR(devs))
- return PTR_ERR(devs);
-
+ num_devs = fscrypt_get_devices(sb, devs);
for (i = 0; i < num_devs; i++) {
if (!blk_crypto_config_supported(devs[i], &crypto_cfg))
- goto out_free_devs;
+ return 0;
}
fscrypt_log_blk_crypto_impl(ci->ci_mode, devs, num_devs, &crypto_cfg);
ci->ci_inlinecrypt = true;
-out_free_devs:
- kfree(devs);
return 0;
}
@@ -164,7 +151,7 @@ int fscrypt_prepare_inline_crypt_key(struct fscrypt_prepared_key *prep_key,
enum blk_crypto_key_type key_type = is_hw_wrapped ?
BLK_CRYPTO_KEY_TYPE_HW_WRAPPED : BLK_CRYPTO_KEY_TYPE_RAW;
struct blk_crypto_key *blk_key;
- struct block_device **devs;
+ struct block_device *devs[FSCRYPT_MAX_DEVICES];
unsigned int num_devs;
unsigned int i;
int err;
@@ -182,17 +169,12 @@ int fscrypt_prepare_inline_crypt_key(struct fscrypt_prepared_key *prep_key,
}
/* Start using blk-crypto on all the filesystem's block devices. */
- devs = fscrypt_get_devices(sb, &num_devs);
- if (IS_ERR(devs)) {
- err = PTR_ERR(devs);
- goto fail;
- }
+ num_devs = fscrypt_get_devices(sb, devs);
for (i = 0; i < num_devs; i++) {
err = blk_crypto_start_using_key(devs[i], blk_key);
if (err)
break;
}
- kfree(devs);
if (err) {
fscrypt_err(inode, "error %d starting to use blk-crypto", err);
goto fail;
@@ -210,20 +192,21 @@ void fscrypt_destroy_inline_crypt_key(struct super_block *sb,
struct fscrypt_prepared_key *prep_key)
{
struct blk_crypto_key *blk_key = prep_key->blk_key;
- struct block_device **devs;
+ struct block_device *devs[FSCRYPT_MAX_DEVICES];
unsigned int num_devs;
unsigned int i;
if (!blk_key)
return;
- /* Evict the key from all the filesystem's block devices. */
- devs = fscrypt_get_devices(sb, &num_devs);
- if (!IS_ERR(devs)) {
- for (i = 0; i < num_devs; i++)
- blk_crypto_evict_key(devs[i], blk_key);
- kfree(devs);
- }
+ /*
+ * Evict the key from all the filesystem's block devices.
+ * This *must* be done before the key is freed.
+ */
+ num_devs = fscrypt_get_devices(sb, devs);
+ for (i = 0; i < num_devs; i++)
+ blk_crypto_evict_key(devs[i], blk_key);
+
kfree_sensitive(blk_key);
}