From 6b76c172b48ecb2c342882c0fe6474b2b973dad0 Mon Sep 17 00:00:00 2001 From: Jamie Liu Date: Thu, 25 Apr 2019 16:03:32 -0700 Subject: Don't enforce NAME_MAX in fs.Dirent.walk(). Maximum filename length is filesystem-dependent, and obtained via statfs::f_namelen. This limit is usually 255 bytes (NAME_MAX), but not always. For example, VFAT supports filenames of up to 255... UCS-2 characters, which Linux conservatively takes to mean UTF-8-encoded bytes: fs/fat/inode.c:fat_statfs(), FAT_LFN_LEN * NLS_MAX_CHARSET_SIZE. As a result, Linux's VFS does not enforce NAME_MAX: $ rg --maxdepth=1 '\WNAME_MAX\W' fs/ include/linux/ fs/libfs.c 38: buf->f_namelen = NAME_MAX; 64: if (dentry->d_name.len > NAME_MAX) include/linux/relay.h 74: char base_filename[NAME_MAX]; /* saved base filename */ include/linux/fscrypt.h 149: * filenames up to NAME_MAX bytes, since base64 encoding expands the length. include/linux/exportfs.h 176: * understanding that it is already pointing to a a %NAME_MAX+1 sized Remove this check from core VFS, and add it to ramfs (and by extension tmpfs), where it is actually applicable: mm/shmem.c:shmem_dir_inode_operations.lookup == simple_lookup *does* enforce NAME_MAX. PiperOrigin-RevId: 245324748 Change-Id: I17567c4324bfd60e31746a5270096e75db963fac --- test/syscalls/linux/chdir.cc | 5 ----- test/syscalls/linux/statfs.cc | 1 + 2 files changed, 1 insertion(+), 5 deletions(-) (limited to 'test/syscalls/linux') diff --git a/test/syscalls/linux/chdir.cc b/test/syscalls/linux/chdir.cc index 4905ffb23..a4b54f0ee 100644 --- a/test/syscalls/linux/chdir.cc +++ b/test/syscalls/linux/chdir.cc @@ -54,11 +54,6 @@ TEST(ChdirTest, NotDir) { EXPECT_THAT(chdir(temp_file.path().c_str()), SyscallFailsWithErrno(ENOTDIR)); } -TEST(ChdirTest, NameTooLong) { - std::string name(NAME_MAX + 1, 'a'); - ASSERT_THAT(chdir(name.c_str()), SyscallFailsWithErrno(ENAMETOOLONG)); -} - TEST(ChdirTest, NotExist) { EXPECT_THAT(chdir("/foo/bar"), SyscallFailsWithErrno(ENOENT)); } diff --git a/test/syscalls/linux/statfs.cc b/test/syscalls/linux/statfs.cc index 1fc9758c9..e1e7fc707 100644 --- a/test/syscalls/linux/statfs.cc +++ b/test/syscalls/linux/statfs.cc @@ -49,6 +49,7 @@ TEST(StatfsTest, NameLen) { struct statfs st; EXPECT_THAT(statfs("/dev/shm", &st), SyscallSucceeds()); + // This assumes that /dev/shm is tmpfs. EXPECT_EQ(st.f_namelen, NAME_MAX); } -- cgit v1.2.3