diff options
author | Ayush Ranjan <ayushranjan@google.com> | 2020-08-13 19:31:17 -0700 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2020-08-13 19:33:56 -0700 |
commit | d6520e1d0592f99161faedef3eba49439b140917 (patch) | |
tree | 302e0b765424bbcb46315b045b40fd707c3645d0 /test/syscalls/linux | |
parent | d3bb50ebf85c1241ec91745eaca9fbbb86eb4211 (diff) |
[vfs2][gofer] Fix file creation flags sent to gofer.
Fixes php runtime test ext/standard/tests/file/readfile_basic.phpt
Fixes #3516
fsgofers only want the access mode in the OpenFlags passed to Create(). If more
flags are supplied (like O_APPEND in this case), read/write from that fd will
fail with EBADF. See runsc/fsgofer/fsgofer.go:WriteAt()
VFS2 was providing more than just access modes. So filtering the flags using
p9.OpenFlagsModeMask == linux.O_ACCMODE fixes the issue.
Gofer in VFS1 also only extracts the access mode flags while making the create
RPC. See pkg/sentry/fs/gofer/path.go:Create()
Even in VFS2, when we open a handle, we extract out only the access mode flags
+ O_TRUNC.
See third_party/gvisor/pkg/sentry/fsimpl/gofer/handle.go:openHandle()
Added a test for this.
PiperOrigin-RevId: 326574829
Diffstat (limited to 'test/syscalls/linux')
-rw-r--r-- | test/syscalls/linux/open.cc | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/test/syscalls/linux/open.cc b/test/syscalls/linux/open.cc index c7147c20b..8f0c9cb49 100644 --- a/test/syscalls/linux/open.cc +++ b/test/syscalls/linux/open.cc @@ -147,6 +147,26 @@ TEST_F(OpenTest, WriteOnly) { EXPECT_THAT(write(wo_file.get(), &buf, 1), SyscallSucceedsWithValue(1)); } +TEST_F(OpenTest, CreateWithAppend) { + std::string data = "text"; + std::string new_file = NewTempAbsPath(); + const FileDescriptor file = ASSERT_NO_ERRNO_AND_VALUE( + Open(new_file, O_WRONLY | O_APPEND | O_CREAT, 0666)); + EXPECT_THAT(write(file.get(), data.c_str(), data.size()), + SyscallSucceedsWithValue(data.size())); + EXPECT_THAT(lseek(file.get(), 0, SEEK_SET), SyscallSucceeds()); + EXPECT_THAT(write(file.get(), data.c_str(), data.size()), + SyscallSucceedsWithValue(data.size())); + + // Check that the size of the file is correct and that the offset has been + // incremented to that size. + struct stat s0; + EXPECT_THAT(fstat(file.get(), &s0), SyscallSucceeds()); + EXPECT_EQ(s0.st_size, 2 * data.size()); + EXPECT_THAT(lseek(file.get(), 0, SEEK_CUR), + SyscallSucceedsWithValue(2 * data.size())); +} + TEST_F(OpenTest, ReadWrite) { char buf; const FileDescriptor rw_file = |