Simplify rejection of unexpected casefold inode flag
Subsystems (2)
cover Simplify rejection of unexpected casefold inode flag
This series makes unexpected casefold flags on inodes be consistently rejected early on so that additional validation isn't needed later on during random filesystem operations. For additional context, refer to the discussion on patch 1 of
https://lore.kernel.org/linux-fsdevel/[email protected]/T/#u
Applies to v6.5-rc6
Eric Biggers (3):
ext4: reject casefold inode flag without casefold feature
ext4: remove redundant checks of s_encoding
libfs: remove redundant checks of s_encoding
fs/ext4/hash.c | 2 +- fs/ext4/inode.c | 5 ++++- fs/ext4/namei.c | 6 +++--- fs/libfs.c | 14 ++------------ 4 files changed, 10 insertions(+), 17 deletions(-)
base-commit: 2ccdd1b13c591d306f0401d98dedc4bdcd02b421
Signature · 8 lines
2.41.0 _______________________________________________ Linux-f2fs-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
PATCH 1/3 ext4: reject casefold inode flag without casefold feature
From: Eric Biggers <[email protected]>
It is invalid for the casefold inode flag to be set without the casefold superblock feature flag also being set. e2fsck already considers this case to be invalid and handles it by offering to clear the casefold flag on the inode. __ext4_iget() also already considered this to be invalid, sort of, but it only got so far as logging an error message; it didn't actually reject the inode. Make it reject the inode so that other code doesn't have to handle this case. This matches what f2fs does.
Note: we could check 's_encoding != NULL' instead of ext4_has_feature_casefold(). This would make the check robust against the casefold feature being enabled by userspace writing to the page cache of the mounted block device. However, it's unsolvable in general for filesystems to be robust against concurrent writes to the page cache of the mounted block device. Though this very particular scenario involving the casefold feature is solvable, we should not pretend that we can support this model, so let's just check the casefold feature. tune2fs already forbids enabling casefold on a mounted filesystem.
--- fs/ext4/inode.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
fs/ext4/inode.c +4 -1
@@ -4940,9 +4940,12 @@ struct inode *__ext4_iget(struct super_block *sb, unsigned long ino, "iget: bogus i_mode (%o)", inode->i_mode); goto bad_inode; } -if (IS_CASEFOLDED (inode) && !ext4_has_feature_casefold (inode->i_sb)) +if (IS_CASEFOLDED (inode) && !ext4_has_feature_casefold (inode->i_sb)) {ext4_error_inode (inode, function, line,0 ,"casefold flag without casefold feature" ); + ret = -EFSCORRUPTED ; + goto bad_inode; + }if ((err_str =check_igot_inode (inode, flags)) !=NULL ) {ext4_error_inode (inode, function, line,0 , err_str); ret = -EFSCORRUPTED ;
Signature · 8 lines
2.41.0 _______________________________________________ Linux-f2fs-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
Re: [PATCH 1/3] ext4: reject casefold inode flag without casefold feature
Quoted 10 lines · Eric Biggers
From: Eric Biggers <[email protected]>
It is invalid for the casefold inode flag to be set without the casefold superblock feature flag also being set. e2fsck already considers this case to be invalid and handles it by offering to clear the casefold flag on the inode.
__ext4_iget()also already considered this to be invalid, sort of, but it only got so far as logging an error message; it didn't actually reject the inode. Make it reject the inode so that other code doesn't have to handle this case. This matches what f2fs does.
Quoted 9 lines
Note: we could check '
s_encoding!= NULL' instead ofext4_has_feature_casefold(). This would make the check robust against the casefold feature being enabled by userspace writing to the page cache of the mounted block device. However, it's unsolvable in general for filesystems to be robust against concurrent writes to the page cache of the mounted block device. Though this very particular scenario involving the casefold feature is solvable, we should not pretend that we can support this model, so let's just check the casefold feature. tune2fs already forbids enabling casefold on a mounted filesystem.
just because we can't fix the general issue for the entire filesystem doesn't mean this case *must not* ever be addressed. What is the advantage of making the code less robust against the syzbot code? Just check sb->s_encoding and be safe later knowing the unicode map is available.
Quoted 24 lines
Signed-off-by Eric Biggers <[email protected]>--- fs/ext4/inode.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)fs/ext4/inode.c +4
-1@@ -4940,9 +4940,12 @@ struct inode *__ext4_iget(struct super_block *sb, unsigned long ino, "iget: bogus i_mode (%o)", inode->i_mode); goto bad_inode; } -if (IS_CASEFOLDED (inode) && !ext4_has_feature_casefold (inode->i_sb)) +if (IS_CASEFOLDED (inode) && !ext4_has_feature_casefold (inode->i_sb)) {ext4_error_inode (inode, function, line,0 ,"casefold flag without casefold feature" ); + ret = -EFSCORRUPTED ; + goto bad_inode; + }if ((err_str =check_igot_inode (inode, flags)) !=NULL ) {ext4_error_inode (inode, function, line,0 , err_str); ret = -EFSCORRUPTED ;
Signature · 7 lines
Gabriel Krisman Bertazi _______________________________________________ Linux-f2fs-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
Re: [PATCH 1/3] ext4: reject casefold inode flag without casefold feature
Quoted 22 lines · Gabriel Krisman Bertazi
Quoted 10 lines · Eric Biggers
From: Eric Biggers <[email protected]>
It is invalid for the casefold inode flag to be set without the casefold superblock feature flag also being set. e2fsck already considers this case to be invalid and handles it by offering to clear the casefold flag on the inode.
__ext4_iget()also already considered this to be invalid, sort of, but it only got so far as logging an error message; it didn't actually reject the inode. Make it reject the inode so that other code doesn't have to handle this case. This matches what f2fs does.Quoted 9 lines
Note: we could check '
s_encoding!= NULL' instead ofext4_has_feature_casefold(). This would make the check robust against the casefold feature being enabled by userspace writing to the page cache of the mounted block device. However, it's unsolvable in general for filesystems to be robust against concurrent writes to the page cache of the mounted block device. Though this very particular scenario involving the casefold feature is solvable, we should not pretend that we can support this model, so let's just check the casefold feature. tune2fs already forbids enabling casefold on a mounted filesystem.
Quoted 6 lines
just because we can't fix the general issue for the entire filesystem doesn't mean this case *must not* ever be addressed. What is the advantage of making the code less robust against the syzbot code? Just check
sb->s_encodingand be safe later knowing the unicode map is available.
Just to make sure, it sounds like you agree that the late checks of ->s_encoding are not needed and only __ext4_iget() should handle it, right? That simplifies the code so it is obviously beneficial if we can do it.
As for whether __ext4_iget() should check the casefold feature or ->s_encoding, we should simply go with the one that makes the code clearer, as per what I've said. I think it's casefold, but it could be ->s_encoding if others prefer.
- Eric
_______________________________________________
Linux-f2fs-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
Re: [PATCH 1/3] ext4: reject casefold inode flag without casefold feature
Quoted 30 lines · Eric Biggers
Quoted 22 lines · Gabriel Krisman Bertazi
Quoted 10 lines · Eric Biggers
From: Eric Biggers <[email protected]>
It is invalid for the casefold inode flag to be set without the casefold superblock feature flag also being set. e2fsck already considers this case to be invalid and handles it by offering to clear the casefold flag on the inode.
__ext4_iget()also already considered this to be invalid, sort of, but it only got so far as logging an error message; it didn't actually reject the inode. Make it reject the inode so that other code doesn't have to handle this case. This matches what f2fs does.Quoted 9 lines
Note: we could check '
s_encoding!= NULL' instead ofext4_has_feature_casefold(). This would make the check robust against the casefold feature being enabled by userspace writing to the page cache of the mounted block device. However, it's unsolvable in general for filesystems to be robust against concurrent writes to the page cache of the mounted block device. Though this very particular scenario involving the casefold feature is solvable, we should not pretend that we can support this model, so let's just check the casefold feature. tune2fs already forbids enabling casefold on a mounted filesystem.Quoted 6 lines
just because we can't fix the general issue for the entire filesystem doesn't mean this case *must not* ever be addressed. What is the advantage of making the code less robust against the syzbot code? Just check
sb->s_encodingand be safe later knowing the unicode map is available.
Quoted 3 lines
Just to make sure, it sounds like you agree that the late checks of ->s_encoding are not needed and only
__ext4_iget()should handle it, right? That simplifies the code so it is obviously beneficial if we can do it.
Yes. After we get the inode from __ext4_iget, I think it doesn't matter if the user went behind our back straight to the block device and changed the superblock to remove the feature bit. If we already loaded ->s_encoding, it won't be unloaded, so only checking at ext4_iget should be enough, as far as I can tell.
Signature · 7 lines
Gabriel Krisman Bertazi _______________________________________________ Linux-f2fs-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
PATCH 2/3 ext4: remove redundant checks of s_encoding
In reply to Eric BiggersFrom: Eric Biggers <[email protected]>
Now that ext4 does not allow inodes with the casefold flag to be instantiated when unsupported, it's unnecessary to repeatedly check for support later on during random filesystem operations.
--- fs/ext4/hash.c | 2 +- fs/ext4/namei.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-)
fs/ext4/hash.c +1 -1
@@ -300,7 +300,7 @@ int ext4fs_dirhash(const struct inode *dir, const char *name, int len,unsigned char *buff;struct qstr qstr = {.name = name, .len = len }; -if (len &&IS_CASEFOLDED (dir) && um && +if (len &&IS_CASEFOLDED (dir) && (!IS_ENCRYPTED (dir) ||fscrypt_has_encryption_key (dir))) { buff =kzalloc (sizeof (char ) *PATH_MAX ,GFP_KERNEL );if (!buff)
fs/ext4/namei.c +3 -3
@@ -1445,7 +1445,7 @@ int ext4_fname_setup_ci_filename(struct inode *dir, const struct qstr *iname,struct dx_hash_info *hinfo = &name->hinfo;int len; -if (!IS_CASEFOLDED (dir) || !dir->i_sb->s_encoding || +if (!IS_CASEFOLDED (dir) || (IS_ENCRYPTED (dir) && !fscrypt_has_encryption_key (dir))) { cf_name->name =NULL ;return 0 ;
@@ -1496,7 +1496,7 @@ static bool ext4_match(struct inode *parent,#endif #if IS_ENABLED(CONFIG_UNICODE) - if (parent->i_sb->s_encoding && IS_CASEFOLDED(parent) && + if (IS_CASEFOLDED(parent) && (!IS_ENCRYPTED(parent) || fscrypt_has_encryption_key(parent))) { if (fname->cf_name.name) { struct qstr cf = {.name = fname->cf_name.name,
@@ -2393,7 +2393,7 @@ static int ext4_add_entry(handle_t *handle, struct dentry *dentry,#if IS_ENABLED (CONFIG_UNICODE )if (sb_has_strict_encoding (sb) &&IS_CASEFOLDED (dir) && - sb->s_encoding &&utf8_validate (sb->s_encoding, &dentry->d_name)) +utf8_validate (sb->s_encoding, &dentry->d_name))return -EINVAL ;#endif
Signature · 8 lines
2.41.0 _______________________________________________ Linux-f2fs-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
PATCH 3/3 libfs: remove redundant checks of s_encoding
In reply to Eric BiggersFrom: Eric Biggers <[email protected]>
Now that neither ext4 nor f2fs allows inodes with the casefold flag to be instantiated when unsupported, it's unnecessary to repeatedly check for support later on during random filesystem operations.
--- fs/libfs.c | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-)
fs/libfs.c +2 -12
@@ -1381,16 +1381,6 @@ bool is_empty_dir_inode(struct inode *inode) }#if IS_ENABLED (CONFIG_UNICODE ) -/* -* Determine if the name of a dentry should be casefolded. -* -* Return: if names will need casefolding -*/ -static bool needs_casefold (const struct inode *dir) -{ -return IS_CASEFOLDED (dir) && dir->i_sb->s_encoding; -} -/** * generic_ci_d_compare - generic d_compare implementation for casefolding filesystems * @dentry: dentry whose name we are checking against
@@ -1411,7 +1401,7 @@ static int generic_ci_d_compare(const struct dentry *dentry, unsigned int len,char strbuf[DNAME_INLINE_LEN ];int ret; -if (!dir || !needs_casefold (dir)) +if (!dir || !IS_CASEFOLDED (dir)) goto fallback;/* * If the dentry name is stored in-line, then it may be concurrently
@@ -1453,7 +1443,7 @@ static int generic_ci_d_hash(const struct dentry *dentry, struct qstr *str)const struct unicode_map *um = sb->s_encoding;int ret =0 ; -if (!dir || !needs_casefold (dir)) +if (!dir || !IS_CASEFOLDED (dir))return 0 ; ret =utf8_casefold_hash (um, dentry, str);
Signature · 8 lines
2.41.0 _______________________________________________ Linux-f2fs-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
Quoted 9 lines · Eric Biggers
This series makes unexpected casefold flags on inodes be consistently rejected early on so that additional validation isn't needed later on during random filesystem operations. For additional context, refer to the discussion on patch 1 of
https://lore.kernel.org/linux-fsdevel/[email protected]/T/#uApplies to v6.5-rc6
[...]
Applied, thanks!
[1/3] ext4: reject casefold inode flag without casefold feature
commit: 3d0f06b5a4e6d09b4a27d701f2ec9a7de8dadbe5
[2/3] ext4: remove redundant checks of s_encoding
commit: fe9ef4ceae694597fe7318aafd7357cc5b85724e
[3/3] libfs: remove redundant checks of s_encoding
commit: 6d7772c4427aaa21251c629d4fabb17e5c10a463Best regards,
Signature · 7 lines
Theodore Ts'o <[email protected]> _______________________________________________ Linux-f2fs-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
This series was applied to jaegeuk/f2fs.git (dev) by Theodore Ts'o <[email protected]>:
Hello:
This series was applied to jaegeuk/f2fs.git (dev)
by Theodore Ts'o <[email protected]>:
Quoted 9 lines · On Mon, 14 Aug 2023 11:29:00 -0700 you wrote:
This series makes unexpected casefold flags on inodes be consistently rejected early on so that additional validation isn't needed later on during random filesystem operations. For additional context, refer to the discussion on patch 1 of
https://lore.kernel.org/linux-fsdevel/[email protected]/T/#uApplies to v6.5-rc6
[...]
Here is the summary with links:
- [f2fs-dev,1/3] ext4: reject casefold inode flag without casefold feature
https://git.kernel.org/jaegeuk/f2fs/c/8216776ccff6 - [f2fs-dev,2/3] ext4: remove redundant checks of s_encoding https://git.kernel.org/jaegeuk/f2fs/c/b81427939590 - [f2fs-dev,3/3] libfs: remove redundant checks of s_encoding https://git.kernel.org/jaegeuk/f2fs/c/af494af38580
You are awesome, thank you!
Signature · 2 lines
Deet-doot-dot, I am a bot. https://korg.docs.kernel.org/patchwork/pwbot.html