fscrypt fixes for v7.4-rc1

- 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
 -----BEGIN PGP SIGNATURE-----
 
 iIoEABYIADIWIQSacvsUNc7UX4ntmEPzXCl4vpKOKwUCauN7sBQcZWJpZ2dlcnNA
 a2VybmVsLm9yZwAKCRDzXCl4vpKOK53LAP4xsKe66IFCsbEzo5whTyuj2AhXRX6Q
 tn3wqD2VWCkZhwD8DEeVcc7f6h+iqK6ANxgziQ7tlGlizuNZujooOuu+IQw=
 =liFT
 -----END PGP SIGNATURE-----

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
This commit is contained in:
Linus Torvalds 2026-10-29 14:00:23 -10:00
commit d89e1d186e
4 changed files with 25 additions and 2 deletions

View File

@ -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);
/*

View File

@ -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;
}

View File

@ -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;

View File

@ -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);