ext4: refuse encryption when block size > page size
cover ext4: refuse encryption when block size > page size
Hi,
encryption is not supported when a filesystem's block size is larger than the page size. Although the kernel refuses to mount such a filesystem if the "encrypt" feature is already set, it is possible to enable it on a mounted filesystem with e.g. tune2fs.
# mkfs.ext4 -b 16384 /dev/vdb # mount /dev/vdb /mnt/ # tune2fs -O encrypt /dev/vdb # mkdir /mnt/foo # fscrypt setup /mnt # fscrypt encrypt /mnt/foo/ # head -c 20M /dev/urandom > /mnt/foo/data # sync [ 116.014221] EXT4-fs warning (device vdb): ext4_end_bio:360: I/O error 19 writing to inode 19 starting block 130040) [ 116.014235] EXT4-fs (vdb): failed to convert unwritten extents to written extents -- potential data loss! (inode 19, error -5) [ 116.014241] Buffer I/O error on device vdb, logical block 130040 [...] [ 116.014264] Buffer I/O error on device vdb, logical block 130049 [ 116.015505] EXT4-fs warning (device vdb): ext4_end_bio:360: I/O error 19 writing to inode 19 starting block 66552) [ 116.015520] EXT4-fs (vdb): failed to convert unwritten extents to written extents -- potential data loss! (inode 19, error -5) [ 116.016451] EXT4-fs warning (device vdb): ext4_end_bio:360: I/O error 19 writing to inode 19 starting block 65784) [ 116.016459] EXT4-fs (vdb): failed to convert unwritten extents to written extents -- potential data loss! (inode 19, error -5)
This affects all kernels starting from v6.19 up to v7.3-rc4.
Note that this still allows encrypted inodes even when the 'encrypt' feature is missing as long as block size <= page size. With v1 encryption policies they can be used normally.
There's an additional bug that only affects kernels between v6.19 and v7.2 (but not v7.3), which will be dealt with separately.
Regards,
Berto
Alberto Garcia (2):
ext4: refuse encryption when block size > page size
ext4: reject encrypted inodes when block size > page size
fs/ext4/crypto.c | 9 +++++++++ fs/ext4/inode.c | 6 ++++++ 2 files changed, 15 insertions(+)
Signature · 1 line
2.47.3
PATCH 1/2 ext4: refuse encryption when block size > page size
Encryption is not supported when a filesystem's block size is larger than the page size, and commit 709f0f1f1bf5 ("ext4: add checks for large folio incompatibilities when BS > PS") added a check to refuse mounting such a filesystem.
However, it is also possible to enable the "encrypt" feature on a filesystem that is already mounted (with tune2fs -O encrypt). Once that happens it won't be possible to mount the filesystem again in the future, but there is nothing preventing the user from setting an encryption policy while the filesystem is still mounted.
Fix this by refusing to set an fscrypt context in ext4_set_context() when the block size is larger than the page size.
--- fs/ext4/crypto.c | 9 +++++++++ 1 file changed, 9 insertions(+)
fs/ext4/crypto.c +9 -0
@@ -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;
Signature · 1 line
2.47.3
[email protected]
AI reviewSashiko has reviewed this patch and found no issues. It looks great!
Quoted 11 lines
Encryption is not supported when a filesystem's block size is larger than the page size, and commit
709f0f1f1bf5("ext4: add checks for large folio incompatibilities when BS > PS") added a check to refuse mounting such a filesystem.However, it is also possible to enable the "encrypt" feature on a filesystem that is already mounted (with tune2fs -O encrypt). Once that happens it won't be possible to mount the filesystem again in the future, but there is nothing preventing the user from setting an encryption policy while the filesystem is still mounted.
Quoted 6 lines
Fix this by refusing to set an fscrypt context in
ext4_set_context()when the block size is larger than the page size.Fixes 709f0f1f1bf5 ("ext4: add checks for large folio incompatibilities when BS > PS")Cc [email protected] # v6.19+Signed-off-by Alberto Garcia <[email protected]>
Sashiko has reviewed this patch and found no issues. It looks great!
Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=1
Quoted 11 lines · Alberto Garcia
Encryption is not supported when a filesystem's block size is larger than the page size, and commit
709f0f1f1bf5("ext4: add checks for large folio incompatibilities when BS > PS") added a check to refuse mounting such a filesystem.However, it is also possible to enable the "encrypt" feature on a filesystem that is already mounted (with tune2fs -O encrypt). Once that happens it won't be possible to mount the filesystem again in the future, but there is nothing preventing the user from setting an encryption policy while the filesystem is still mounted.
Quoted 6 lines
Fix this by refusing to set an fscrypt context in
ext4_set_context()when the block size is larger than the page size.Fixes 709f0f1f1bf5 ("ext4: add checks for large folio incompatibilities when BS > PS")Cc [email protected] # v6.19+Signed-off-by Alberto Garcia <[email protected]>
Thanks for the patch, feel free to add:
Quoted 24 lines
--- fs/ext4/crypto.c | 9 +++++++++ 1 file changed, 9 insertions(+)fs/ext4/crypto.c +9
-0@@ -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;
PATCH 2/2 ext4: reject encrypted inodes when block size > page size
In reply to Alberto GarciaEncryption is not supported when a filesystem's block size is larger than the page size. ext4_check_large_folio() refuses to mount a filesystem like that if the "encrypt" feature is already enabled, and ext4_set_context() refuses to create encrypted inodes if the feature is enabled after mounting.
However, a corrupted or hand-crafted filesystem can still have encrypted inodes even if the "encrypt" feature is not set, and those inodes can be unlocked if they're using v1 policies.
Check this in __ext4_iget() and reject them as corrupted.
--- fs/ext4/inode.c | 6 ++++++ 1 file changed, 6 insertions(+)
fs/ext4/inode.c +6 -0
@@ -5671,6 +5671,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);
Signature · 1 line
2.47.3
[email protected]
AI reviewRe: [PATCH 2/2] ext4: reject encrypted inodes when block size > page size
Sashiko has reviewed this patch and found no issues. It looks great!
Quoted 10 lines
Encryption is not supported when a filesystem's block size is larger than the page size.
ext4_check_large_folio()refuses to mount a filesystem like that if the "encrypt" feature is already enabled, andext4_set_context()refuses to create encrypted inodes if the feature is enabled after mounting.However, a corrupted or hand-crafted filesystem can still have encrypted inodes even if the "encrypt" feature is not set, and those inodes can be unlocked if they're using v1 policies.
Quoted 6 lines
Check this in
__ext4_iget()and reject them as corrupted.Fixes 709f0f1f1bf5 ("ext4: add checks for large folio incompatibilities when BS > PS")Suggested-by Eric Biggers <[email protected]>Cc [email protected] # v6.19+Signed-off-by Alberto Garcia <[email protected]>
Sashiko has reviewed this patch and found no issues. It looks great!
Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=2
Re: [PATCH 2/2] ext4: reject encrypted inodes when block size > page size
In reply to Alberto GarciaQuoted 10 lines · Alberto Garcia
Encryption is not supported when a filesystem's block size is larger than the page size.
ext4_check_large_folio()refuses to mount a filesystem like that if the "encrypt" feature is already enabled, andext4_set_context()refuses to create encrypted inodes if the feature is enabled after mounting.However, a corrupted or hand-crafted filesystem can still have encrypted inodes even if the "encrypt" feature is not set, and those inodes can be unlocked if they're using v1 policies.
Quoted 6 lines
Check this in
__ext4_iget()and reject them as corrupted.Fixes 709f0f1f1bf5 ("ext4: add checks for large folio incompatibilities when BS > PS")Suggested-by Eric Biggers <[email protected]>Cc [email protected] # v6.19+Signed-off-by Alberto Garcia <[email protected]>
Looks good, feel free to add:
Quoted 21 lines
--- fs/ext4/inode.c | 6 ++++++ 1 file changed, 6 insertions(+)fs/ext4/inode.c +6
-0@@ -5671,6 +5671,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);
Quoted 38 lines · Alberto Garcia
Hi,
encryption is not supported when a filesystem's block size is larger than the page size. Although the kernel refuses to mount such a filesystem if the "encrypt" feature is already set, it is possible to enable it on a mounted filesystem with e.g. tune2fs.
# mkfs.ext4 -b 16384 /dev/vdb # mount /dev/vdb /mnt/ # tune2fs -O encrypt /dev/vdb # mkdir /mnt/foo # fscrypt setup /mnt # fscrypt encrypt /mnt/foo/ # head -c 20M /dev/urandom > /mnt/foo/data # sync [ 116.014221] EXT4-fs warning (device vdb): ext4_end_bio:360: I/O error 19 writing to inode 19 starting block 130040) [ 116.014235] EXT4-fs (vdb): failed to convert unwritten extents to written extents -- potential data loss! (inode 19, error -5) [ 116.014241] Buffer I/O error on device vdb, logical block 130040 [...] [ 116.014264] Buffer I/O error on device vdb, logical block 130049 [ 116.015505] EXT4-fs warning (device vdb): ext4_end_bio:360: I/O error 19 writing to inode 19 starting block 66552) [ 116.015520] EXT4-fs (vdb): failed to convert unwritten extents to written extents -- potential data loss! (inode 19, error -5) [ 116.016451] EXT4-fs warning (device vdb): ext4_end_bio:360: I/O error 19 writing to inode 19 starting block 65784) [ 116.016459] EXT4-fs (vdb): failed to convert unwritten extents to written extents -- potential data loss! (inode 19, error -5)This affects all kernels starting from v6.19 up to v7.3-rc4.
Note that this still allows encrypted inodes even when the 'encrypt' feature is missing as long as block size <= page size. With v1 encryption policies they can be used normally.
There's an additional bug that only affects kernels between v6.19 and v7.2 (but not v7.3), which will be dealt with separately.
Regards,
Berto
Quoted 7 lines
Alberto Garcia (2):
ext4: refuse encryption when block size > page size
ext4: reject encrypted inodes when block size > page sizefs/ext4/crypto.c | 9 +++++++++ fs/ext4/inode.c | 6 ++++++ 2 files changed, 15 insertions(+)
- Eric
Eric Biggers
maintainerQuoted 3 lines · Alberto Garcia
Alberto Garcia (2):
ext4: refuse encryption when block size > page size
ext4: reject encrypted inodes when block size > page size
These didn't get taken through the ext4 tree. So I've gone ahead and applied them to the fscrypt tree
(https://git.kernel.org/pub/scm/fs/fscrypt/linux.git/log/?h=for-next).
- Eric