diff options
author | Eric Biggers <ebiggers@google.com> | 2022-05-14 10:59:29 -0700 |
---|---|---|
committer | Jaegeuk Kim <jaegeuk@kernel.org> | 2022-05-17 11:19:23 -0700 |
commit | b5639bb4313b9d455fc9fc4768d23a5e4ca8cb9d (patch) | |
tree | 01e37a83ad3acc9d6115d49787eb63927056c787 /fs/f2fs/f2fs.h | |
parent | c81d5bae404abc6b257667e84d39b9b50c7063d4 (diff) | |
download | linux-b5639bb4313b9d455fc9fc4768d23a5e4ca8cb9d.tar.gz linux-b5639bb4313b9d455fc9fc4768d23a5e4ca8cb9d.tar.bz2 linux-b5639bb4313b9d455fc9fc4768d23a5e4ca8cb9d.zip |
f2fs: don't use casefolded comparison for "." and ".."
Tryng to rename a directory that has all following properties fails with
EINVAL and triggers the 'WARN_ON_ONCE(!fscrypt_has_encryption_key(dir))'
in f2fs_match_ci_name():
- The directory is casefolded
- The directory is encrypted
- The directory's encryption key is not yet set up
- The parent directory is *not* encrypted
The problem is incorrect handling of the lookup of ".." to get the
parent reference to update. fscrypt_setup_filename() treats ".." (and
".") specially, as it's never encrypted. It's passed through as-is, and
setting up the directory's key is not attempted. As the name isn't a
no-key name, f2fs treats it as a "normal" name and attempts a casefolded
comparison. That breaks the assumption of the WARN_ON_ONCE() in
f2fs_match_ci_name() which assumes that for encrypted directories,
casefolded comparisons only happen when the directory's key is set up.
We could just remove this WARN_ON_ONCE(). However, since casefolding is
always a no-op on "." and ".." anyway, let's instead just not casefold
these names. This results in the standard bytewise comparison.
Fixes: 7ad08a58bf67 ("f2fs: Handle casefolding with Encryption")
Cc: <stable@vger.kernel.org> # v5.11+
Signed-off-by: Eric Biggers <ebiggers@google.com>
Reviewed-by: Gabriel Krisman Bertazi <krisman@collabora.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Diffstat (limited to 'fs/f2fs/f2fs.h')
-rw-r--r-- | fs/f2fs/f2fs.h | 10 |
1 files changed, 5 insertions, 5 deletions
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 492af5b96de1..e9e32bc814df 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -508,11 +508,11 @@ struct f2fs_filename { #if IS_ENABLED(CONFIG_UNICODE) /* * For casefolded directories: the casefolded name, but it's left NULL - * if the original name is not valid Unicode, if the directory is both - * casefolded and encrypted and its encryption key is unavailable, or if - * the filesystem is doing an internal operation where usr_fname is also - * NULL. In all these cases we fall back to treating the name as an - * opaque byte sequence. + * if the original name is not valid Unicode, if the original name is + * "." or "..", if the directory is both casefolded and encrypted and + * its encryption key is unavailable, or if the filesystem is doing an + * internal operation where usr_fname is also NULL. In all these cases + * we fall back to treating the name as an opaque byte sequence. */ struct fscrypt_str cf_name; #endif |