diff --git a/fs/crypto/keyring.c b/fs/crypto/keyring.c index 874cc183ee62..09364fddcb7a 100644 --- a/fs/crypto/keyring.c +++ b/fs/crypto/keyring.c @@ -561,8 +561,10 @@ static int add_master_key(struct super_block *sb, if (secret->is_hw_wrapped) { err = fscrypt_derive_sw_secret(sb, secret->bytes, secret->size, sw_secret); - if (err) + if (err) { + memzero_explicit(sw_secret, sizeof(sw_secret)); return err; + } kdf_key = sw_secret; kdf_key_size = sizeof(sw_secret); /* diff --git a/fs/crypto/keysetup.c b/fs/crypto/keysetup.c index 892044ebcaca..a77b889d7578 100644 --- a/fs/crypto/keysetup.c +++ b/fs/crypto/keysetup.c @@ -205,8 +205,14 @@ fscrypt_find_mode_key(struct fscrypt_master_key *mk, u8 hkdf_context, if (node->hkdf_context == hkdf_context && node->mode_num == mode_num && node->data_unit_bits == ci->ci_data_unit_bits && - fscrypt_is_key_prepared(&node->key, ci)) + fscrypt_is_key_prepared(&node->key, ci)) { + /* + * Upgrade the RCU dereference to a full ACQUIRE, so + * that blk-crypto global state is seen as initialized. + */ + smp_acquire__after_ctrl_dep(); return &node->key; + } } return NULL; } diff --git a/fs/ext4/crypto.c b/fs/ext4/crypto.c index 1a0fccb084ef..318b2eaea741 100644 --- a/fs/ext4/crypto.c +++ b/fs/ext4/crypto.c @@ -156,6 +156,15 @@ static int ext4_set_context(struct inode *inode, const void *ctx, size_t len, if (ext4_test_inode_flag(inode, EXT4_INODE_DAX)) return -EOPNOTSUPP; + /* + * Encryption is not supported when the block size is larger + * than the page size. This is rejected at mount time by + * ext4_check_large_folio(), and this check here is for the case + * when the 'encrypt' feature is enabled on a mounted filesystem. + */ + if (inode->i_sb->s_blocksize > PAGE_SIZE) + return -EOPNOTSUPP; + res = ext4_convert_inline_data(inode); if (res) return res; diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index b4d581aa5ee1..10cd85d4c721 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -6571,6 +6571,12 @@ struct inode *__ext4_iget(struct super_block *sb, unsigned long ino, ret = -EFSCORRUPTED; goto bad_inode; } + if (IS_ENCRYPTED(inode) && sb->s_blocksize > PAGE_SIZE) { + ext4_error_inode(inode, function, line, 0, + "encrypted inode with block size larger than page size"); + ret = -EFSCORRUPTED; + goto bad_inode; + } ext4_set_inode_mapping_order(inode);