mirror of
https://github.com/torvalds/linux.git
synced 2026-09-22 04:34:03 +02:00
fat: reject name longer than NAME_MAX in msdos_format_name()
msdos_format_name() performs no upper-bound check on the input name length. It silently truncates an arbitrarily long name into the 8.3 form (11 bytes) and returns success. The subsequent fat_scan() then matches only against these 11 truncated bytes, so it returns an inode as long as any entry with the same 8.3 name exists on disk. For example, passing a 300-byte name of all 'A's returns 0 with res set to "AAAAAAAA" (8 'A's + 3 padding spaces), reporting success for a name far longer than NAME_MAX. As a result, when a user calls open() on a path component longer than NAME_MAX (255) bytes, the VFS only enforces PATH_MAX, not the length of an individual component. The dentry keeps the original long name but gets an inode attached and becomes positive. Later in vfs_open() -> fsnotify_open() -> fanotify_info_copy_name() triggers WARN_ON_ONCE(), and the event is reported to userspace with an empty name. vfat is not affected, as create goes through xlate_to_uni() which refuses names longer than FAT_LFN_LEN. Fix this by checking 'len > NAME_MAX' at the entry of msdos_format_name(), the single entry point for all msdos name handling, aligning with the NAME_MAX check that xfs/9p/ceph/simple_lookup() perform at lookup. Signed-off-by: Zizhi Wo <wozizhi@huawei.com> Link: https://patch.msgid.link/20260629130943.3671939-1-wozizhi@huaweicloud.com Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
This commit is contained in:
parent
dc59e4fea9
commit
9d7ed813ee
|
|
@ -29,6 +29,9 @@ static int msdos_format_name(const unsigned char *name, int len,
|
|||
unsigned char c;
|
||||
int space;
|
||||
|
||||
if (len > NAME_MAX)
|
||||
return -ENAMETOOLONG;
|
||||
|
||||
if (name[0] == '.') { /* dotfile because . and .. already done */
|
||||
if (opts->dotsOK) {
|
||||
/* Get rid of dot - test for it elsewhere */
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user