summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJamie Liu <jamieliu@google.com>2021-10-26 00:19:54 -0700
committergVisor bot <gvisor-bot@google.com>2021-10-26 00:22:29 -0700
commit12480f1c4b49234a3761856e40d4d122695b610f (patch)
treed8c03d4a5174f397928a4c6d11c25216b3f15b4b
parent4d07fc952d6bb5aa70b4bc9ff5e6457987f1721c (diff)
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
-rw-r--r--pkg/sentry/fsimpl/gofer/filesystem.go6
-rw-r--r--test/syscalls/linux/statfs.cc11
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