CVE-2023-45897 (published 2023-10-28T21:15Z)

exfatprogs before 1.2.2 allows out-of-bounds memory access, such as in read_file_dentry_set.

CVSS v3 base score: 5.5, MEDIUM (CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:N)

Weakness information:
cwe_id: CWE-125
cwe_name: Out-of-bounds Read
description: The product reads data past the end, or before the beginning, of the intended buffer.
extended_description: 
            
            
             
			 
         
         

Fix information:
repo_url: https://github.com/exfatprogs/exfatprogs
commit_details: repo_url: https://github.com/exfatprogs/exfatprogs
author: Yuezhang Mo
author_date: 2023-08-10 14:10:05+08:00
msg: fsck: fix out-of-bounds memory access

The size of utf16_name is ENTRY_NAME_MAX, we should pass
ENTRY_NAME_MAX to exfat_utf16_len(), not ENTRY_NAME_MAX*2.

exfat_utf16_enc() returns the length of the utf16-encoded
filename, it is not needed to call exfat_utf16_len().

Signed-off-by: Yuezhang Mo <Yuezhang.Mo@sony.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
repository: repo_url: https://github.com/exfatprogs/exfatprogs
repo_name: exfatprogs/exfatprogs
description: exFAT filesystem userspace utilities
repo_language: C
owner: exfatprogs
file_changes: filename: fsck.c
change_type: ModificationType.MODIFY
diff: @@ -811,7 +811,7 @@ ask_again:
 		char *rename = NULL;
 		__u16 hash;
 		struct exfat_dentry *stream_de;
-		int name_len, ret;
+		int ret;
 
 		switch (num) {
 		case 1:
@@ -840,11 +840,11 @@ ask_again:
 		if (ret < 0)
 			return ret;
 
+		ret >>= 1;
 		memcpy(dentry->name_unicode, utf16_name, ENTRY_NAME_MAX * 2);
-		name_len = exfat_utf16_len(utf16_name, ENTRY_NAME_MAX * 2);
-		hash = exfat_calc_name_hash(iter->exfat, utf16_name, (int)name_len);
+		hash = exfat_calc_name_hash(iter->exfat, utf16_name, ret);
 		exfat_de_iter_get_dirty(iter, 1, &stream_de);
-		stream_de->stream_name_len = (__u8)name_len;
+		stream_de->stream_name_len = (__u8)ret;
 		stream_de->stream_name_hash = cpu_to_le16(hash);
 	}
 

programming_language: C
repo_url: https://github.com/exfatprogs/exfatprogs
commit_details: repo_url: https://github.com/exfatprogs/exfatprogs
author: Hyunchul Lee
author_date: 2023-10-26 14:25:52+09:00
msg: exfat2img: fix out-of-bounds write in read_file_dentry_set

if SecondaryCount is greater than (2 + the max number
of File Name entries), writing to memory outside
the node->name could happen.

Reported-by: Yuezhang Mo <Yuezhang.Mo@sony.com>
Signed-off-by: Hyunchul Lee <hyc.lee@gmail.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
repository: repo_url: https://github.com/exfatprogs/exfatprogs
repo_name: exfatprogs/exfatprogs
description: exFAT filesystem userspace utilities
repo_language: C
owner: exfatprogs
file_changes: filename: exfat2img.c
change_type: ModificationType.MODIFY
diff: @@ -319,7 +319,7 @@ static int read_file_dentry_set(struct exfat_de_iter *iter,
 	if (!node)
 		return -ENOMEM;
 
-	for (i = 2; i <= file_de->file_num_ext; i++) {
+	for (i = 2; i <= MIN(file_de->file_num_ext, 1 + MAX_NAME_DENTRIES); i++) {
 		ret = exfat_de_iter_get(iter, i, &dentry);
 		if (ret || dentry->type != EXFAT_NAME)
 			break;

programming_language: C
repo_url: https://github.com/exfatprogs/exfatprogs
commit_details: repo_url: https://github.com/exfatprogs/exfatprogs
author: Hyunchul Lee
author_date: 2023-10-25 15:29:29+09:00
msg: fsck: fix out-of-bounds write in read_file_dentry_set

if SecondaryCount is greater than (2 + the max number
of File Name entries), writing to memory outside
the node->name could happen.

Reported-by: Maxim Suhanov <dfirblog@gmail.com>
Signed-off-by: Hyunchul Lee <hyc.lee@gmail.com>
Reviewed-by: Yuezhang Mo <Yuezhang.Mo@sony.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
repository: repo_url: https://github.com/exfatprogs/exfatprogs
repo_name: exfatprogs/exfatprogs
description: exFAT filesystem userspace utilities
repo_language: C
owner: exfatprogs
file_changes: filename: fsck.c
change_type: ModificationType.MODIFY
diff: @@ -774,7 +774,7 @@ static int read_file_dentry_set(struct exfat_de_iter *iter,
 	if (!node)
 		return -ENOMEM;
 
-	for (i = 2; i <= file_de->file_num_ext; i++) {
+	for (i = 2; i <= MIN(file_de->file_num_ext, 1 + MAX_NAME_DENTRIES); i++) {
 		ret = exfat_de_iter_get(iter, i, &dentry);
 		if (ret || dentry->type != EXFAT_NAME) {
 			if (i > 2 && repair_file_ask(iter, NULL, ER_DE_NAME,

programming_language: C
filename: exfat_ondisk.h
change_type: ModificationType.MODIFY
diff: @@ -40,6 +40,7 @@
 /* exFAT allows 8388608(256MB) directory entries */
 #define MAX_EXFAT_DENTRIES	8388608
 #define MIN_FILE_DENTRIES	3
+#define MAX_NAME_DENTRIES	17
 
 /* dentry types */
 #define MSDOS_DELETED		0xE5	/* deleted mark */

programming_language: C