Message ID | 20230713130310.8445-1-linkinjeon@kernel.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | exfat: check if filename entries exceeds max filename length | expand |
> From: Namjae Jeon <linkinjeon@kernel.org> > Sent: Thursday, July 13, 2023 9:03 PM > exfat_extract_uni_name copies characters from a given file name entry into > the 'uniname' variable. This variable is actually defined on the stack of the > exfat_readdir() function. According to the definition of the 'exfat_uni_name' > type, the file name should be limited 255 characters (+ null teminator space), > but the exfat_get_uniname_from_ext_entry() > function can write more characters because there is no check if filename > entries exceeds max filename length. This patch add the check not to copy > filename characters when exceeding max filename length. This case is not compliant with the exFAT file system specification, I think it is better to return an error and let the user fix it with fsck. The current fix may result in multiple files with the same name in a directory. Such as, there are files $(filename255) and files $(filename255)1, $(filename255)2... in a directory, but they will all be found as $(filename255).
2023-07-17 13:43 GMT+09:00, Yuezhang.Mo@sony.com <Yuezhang.Mo@sony.com>: > >> From: Namjae Jeon <linkinjeon@kernel.org> >> Sent: Thursday, July 13, 2023 9:03 PM >> exfat_extract_uni_name copies characters from a given file name entry >> into >> the 'uniname' variable. This variable is actually defined on the stack of >> the >> exfat_readdir() function. According to the definition of the >> 'exfat_uni_name' >> type, the file name should be limited 255 characters (+ null teminator >> space), >> but the exfat_get_uniname_from_ext_entry() >> function can write more characters because there is no check if filename >> entries exceeds max filename length. This patch add the check not to copy >> filename characters when exceeding max filename length. > > This case is not compliant with the exFAT file system specification, I think > it is > better to return an error and let the user fix it with fsck. > The current fix may result in multiple files with the same name in a > directory. > > Such as, there are files $(filename255) and files $(filename255)1, > $(filename255)2... > in a directory, but they will all be found as $(filename255). We were considering between handling it as an error and like this patch. In windows, such files is visible and can be accessed without any error like this patch. And please don't assume that fsck can be run in all cases. In some products and scenarios, fsck cannot be executed and should not be expected. I can add an error print to make the user run fsck. > > >
diff --git a/fs/exfat/dir.c b/fs/exfat/dir.c index 957574180a5e..bc48f3329921 100644 --- a/fs/exfat/dir.c +++ b/fs/exfat/dir.c @@ -34,6 +34,7 @@ static int exfat_get_uniname_from_ext_entry(struct super_block *sb, { int i, err; struct exfat_entry_set_cache es; + unsigned int uni_len = 0, len; err = exfat_get_dentry_set(&es, sb, p_dir, entry, ES_ALL_ENTRIES); if (err) @@ -52,7 +53,10 @@ static int exfat_get_uniname_from_ext_entry(struct super_block *sb, if (exfat_get_entry_type(ep) != TYPE_EXTEND) break; - exfat_extract_uni_name(ep, uniname); + len = exfat_extract_uni_name(ep, uniname); + uni_len += len; + if (len != EXFAT_FILE_NAME_LEN || uni_len >= MAX_NAME_LENGTH) + break; uniname += EXFAT_FILE_NAME_LEN; } @@ -1079,7 +1083,8 @@ int exfat_find_dir_entry(struct super_block *sb, struct exfat_inode_info *ei, if (entry_type == TYPE_EXTEND) { unsigned short entry_uniname[16], unichar; - if (step != DIRENT_STEP_NAME) { + if (step != DIRENT_STEP_NAME || + name_len >= MAX_NAME_LENGTH) { step = DIRENT_STEP_FILE; continue; }