]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
exfat: check if filename entries exceeds max filename length
authorNamjae Jeon <linkinjeon@kernel.org>
Thu, 13 Jul 2023 12:59:37 +0000 (21:59 +0900)
committerNamjae Jeon <linkinjeon@kernel.org>
Thu, 13 Jul 2023 13:02:25 +0000 (22:02 +0900)
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.

Cc: stable@vger.kernel.org
Cc: Yuezhang Mo <Yuezhang.Mo@sony.com>
Reported-by: Maxim Suhanov <dfirblog@gmail.com>
Reviewed-by: Sungjong Seo <sj1557.seo@samsung.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
fs/exfat/dir.c

index 957574180a5e3e0e80b7830ecf8ec51b989a3e60..bc48f33299218069bbc959ad71bdabf2a176826c 100644 (file)
@@ -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 @@ rewind:
                        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;
                                }