diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2026-10-29 14:00:23 -1000 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2026-10-29 14:00:23 -1000 |
| commit | d89e1d186ec9271bf78e62771779e9fc03bf0fc3 (patch) | |
| tree | 0c40997edac11ec31e84c61c0f291df109f7288f | |
| parent | 0ff8f40110872ecd3a9918e56ddd0ff1b46fb10e (diff) | |
| parent | a5e894bc87b76fd980075892ba77e6bdeeb5e4d0 (diff) | |
| download | linux-d89e1d186ec9271bf78e62771779e9fc03bf0fc3.tar.gz linux-d89e1d186ec9271bf78e62771779e9fc03bf0fc3.zip | |
Merge tag 'fscrypt-for-linus' of git://git.kernel.org/pub/scm/fs/fscrypt/linux
Pull fscrypt fixes from Eric Biggers:
- Add more checks to prevent encryption on "large block size" ext4
filesystems (s_blocksize > PAGE_SIZE), which isn't supported yet.
There was already a mount-time check, but it wasn't enough.
- Add missing memory barrier to fscrypt_find_mode_key()
- Add missing zeroization in an error path
* tag 'fscrypt-for-linus' of git://git.kernel.org/pub/scm/fs/fscrypt/linux:
ext4: reject encrypted inodes when block size > page size
ext4: refuse encryption when block size > page size
fscrypt: Fix missing barrier in fscrypt_find_mode_key()
fscrypt: Explicitly zeroize sw_secret in error path
| -rw-r--r-- | fs/crypto/keyring.c | 4 | ||||
| -rw-r--r-- | fs/crypto/keysetup.c | 8 | ||||
| -rw-r--r-- | fs/ext4/crypto.c | 9 | ||||
| -rw-r--r-- | fs/ext4/inode.c | 6 |
4 files changed, 25 insertions, 2 deletions
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); |
