linux/fs/exfat
Bryam Vargas fae76a94b3 exfat: bound uniname advance in exfat_find_dir_entry()
commit 3a1230e7b0 upstream.

In exfat_find_dir_entry(), each TYPE_EXTEND (file name) entry advances the
output pointer by a fixed amount while the loop guard only tracks the
accumulated name length:

	if (++order == 2)
		uniname = p_uniname->name;
	else
		uniname += EXFAT_FILE_NAME_LEN;
	len = exfat_extract_uni_name(ep, entry_uniname);
	name_len += len;
	unichar = *(uniname+len);
	*(uniname+len) = 0x0;

uniname grows by EXFAT_FILE_NAME_LEN (15) per name entry, but name_len
grows only by the actual extracted length, which is shorter when a name
fragment contains an early NUL.  The only guard is
`name_len >= MAX_NAME_LENGTH`, so a crafted directory with many short
name fragments lets uniname run far past the
p_uniname->name[MAX_NAME_LENGTH + 3] buffer while name_len stays small,
causing an out-of-bounds read and write at *(uniname+len).

The sibling extractor exfat_get_uniname_from_ext_entry() already stops
on a short fragment (the lockstep `len != EXFAT_FILE_NAME_LEN` guard
added in commit d42334578e ("exfat: check if filename entries exceeds
max filename length")); exfat_find_dir_entry() never got the
equivalent.  Track the per-entry write offset as a count and reject a
fragment once the offset, or the offset plus the extracted length, would
exceed MAX_NAME_LENGTH, before forming the output pointer.

Fixes: ca06197382 ("exfat: add directory operations")
Cc: stable@vger.kernel.org
Suggested-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Bryam Vargas <hexlabsecurity@proton.me>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
History 2026-07-24 15:51:25 +02:00
..
balloc.c exfat: fix soft lockup in exfat_clear_bitmap 2025-03-13 12:51:07 +01:00
cache.c exfat: fix use of uninitialized spinlock on error path 2020-10-07 14:27:13 +09:00
dir.c exfat: bound uniname advance in exfat_find_dir_entry() 2026-07-24 15:51:25 +02:00
exfat_fs.h exfat: fix soft lockup in exfat_clear_bitmap 2025-03-13 12:51:07 +01:00
exfat_raw.h exfat: fix shift-out-of-bounds in exfat_fill_super() 2021-02-22 09:55:13 +09:00
fatent.c exfat: limit log print for IO error 2025-12-07 06:09:24 +09:00
file.c exfat: fix inode->i_blocks for non-512 byte sector size device 2023-03-10 09:39:58 +01:00
inode.c exfat: fix inode->i_blocks for non-512 byte sector size device 2023-03-10 09:39:58 +01:00
Kconfig exfat: Improve wording of EXFAT_DEFAULT_IOCHARSET config option 2020-06-09 16:48:39 +09:00
Makefile exfat: add Kconfig and Makefile 2020-03-05 21:00:40 -05:00
misc.c exfat: write multiple sectors at once 2020-08-12 08:31:11 +09:00
namei.c exfat: fix uninit-value in __exfat_get_dentry_set 2024-12-14 19:51:14 +01:00
nls.c exfat: fix double free in delayed_free 2025-06-27 11:05:28 +01:00
super.c exfat: fix remount failure in different process environments 2026-01-19 13:09:47 +01:00