From 12480f1c4b49234a3761856e40d4d122695b610f Mon Sep 17 00:00:00 2001 From: Jamie Liu Date: Tue, 26 Oct 2021 00:19:54 -0700 Subject: Ensure statfs::f_namelen is set by VFS2 gofer statfs/fstatfs. VFS1 discards the value of f_namelen returned by the filesystem and returns NAME_MAX unconditionally instead, so it doesn't run into this. Also set f_frsize for completeness. PiperOrigin-RevId: 405579707 --- pkg/sentry/fsimpl/gofer/filesystem.go | 6 ++++-- test/syscalls/linux/statfs.cc | 11 +++++++++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/pkg/sentry/fsimpl/gofer/filesystem.go b/pkg/sentry/fsimpl/gofer/filesystem.go index 23c8b8ce3..bf58a9def 100644 --- a/pkg/sentry/fsimpl/gofer/filesystem.go +++ b/pkg/sentry/fsimpl/gofer/filesystem.go @@ -1696,7 +1696,7 @@ func (fs *filesystem) StatFSAt(ctx context.Context, rp *vfs.ResolvingPath) (linu if err := d.controlFDLisa.StatFSTo(ctx, &statFS); err != nil { return linux.Statfs{}, err } - if statFS.NameLength > maxFilenameLen { + if statFS.NameLength == 0 || statFS.NameLength > maxFilenameLen { statFS.NameLength = maxFilenameLen } return linux.Statfs{ @@ -1705,6 +1705,7 @@ func (fs *filesystem) StatFSAt(ctx context.Context, rp *vfs.ResolvingPath) (linu // something completely random, use a standard value. Type: linux.V9FS_MAGIC, BlockSize: statFS.BlockSize, + FragmentSize: statFS.BlockSize, Blocks: statFS.Blocks, BlocksFree: statFS.BlocksFree, BlocksAvailable: statFS.BlocksAvailable, @@ -1718,7 +1719,7 @@ func (fs *filesystem) StatFSAt(ctx context.Context, rp *vfs.ResolvingPath) (linu return linux.Statfs{}, err } nameLen := uint64(fsstat.NameLength) - if nameLen > maxFilenameLen { + if nameLen == 0 || nameLen > maxFilenameLen { nameLen = maxFilenameLen } return linux.Statfs{ @@ -1727,6 +1728,7 @@ func (fs *filesystem) StatFSAt(ctx context.Context, rp *vfs.ResolvingPath) (linu // something completely random, use a standard value. Type: linux.V9FS_MAGIC, BlockSize: int64(fsstat.BlockSize), + FragmentSize: int64(fsstat.BlockSize), Blocks: fsstat.Blocks, BlocksFree: fsstat.BlocksFree, BlocksAvailable: fsstat.BlocksAvailable, diff --git a/test/syscalls/linux/statfs.cc b/test/syscalls/linux/statfs.cc index d057cdc09..b447b5cce 100644 --- a/test/syscalls/linux/statfs.cc +++ b/test/syscalls/linux/statfs.cc @@ -34,17 +34,19 @@ TEST(StatfsTest, CannotStatBadPath) { EXPECT_THAT(statfs(temp_file.c_str(), &st), SyscallFailsWithErrno(ENOENT)); } -TEST(StatfsTest, InternalTmpfs) { +TEST(StatfsTest, TempPath) { auto temp_file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile()); struct statfs st; EXPECT_THAT(statfs(temp_file.path().c_str(), &st), SyscallSucceeds()); + EXPECT_GT(st.f_namelen, 0); } TEST(StatfsTest, InternalDevShm) { struct statfs st; EXPECT_THAT(statfs("/dev/shm", &st), SyscallSucceeds()); + EXPECT_GT(st.f_namelen, 0); // This assumes that /dev/shm is tmpfs. // Note: We could be an overlay on some configurations. EXPECT_TRUE(st.f_type == TMPFS_MAGIC || st.f_type == OVERLAYFS_SUPER_MAGIC); @@ -55,13 +57,14 @@ TEST(FstatfsTest, CannotStatBadFd) { EXPECT_THAT(fstatfs(-1, &st), SyscallFailsWithErrno(EBADF)); } -TEST(FstatfsTest, InternalTmpfs) { +TEST(FstatfsTest, TempPath) { auto temp_file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile()); const FileDescriptor fd = ASSERT_NO_ERRNO_AND_VALUE(Open(temp_file.path(), O_RDONLY)); struct statfs st; EXPECT_THAT(fstatfs(fd.get(), &st), SyscallSucceeds()); + EXPECT_GT(st.f_namelen, 0); } TEST(FstatfsTest, CanStatFileWithOpath) { @@ -81,6 +84,10 @@ TEST(FstatfsTest, InternalDevShm) { struct statfs st; EXPECT_THAT(fstatfs(fd.get(), &st), SyscallSucceeds()); + EXPECT_GT(st.f_namelen, 0); + // This assumes that /dev/shm is tmpfs. + // Note: We could be an overlay on some configurations. + EXPECT_TRUE(st.f_type == TMPFS_MAGIC || st.f_type == OVERLAYFS_SUPER_MAGIC); } } // namespace -- cgit v1.2.3