Make directory open flags checks consistent in tmpfs and kernfs.

Overlayfs and goferfs seem to be up to date.
Updated syscall tests.

PiperOrigin-RevId: 503521750
This commit is contained in:
Ayush Ranjan
2023-01-20 14:22:38 -08:00
committed by gVisor bot
parent 492d7a9811
commit a58df80df3
3 changed files with 29 additions and 4 deletions
+13
View File
@@ -618,6 +618,19 @@ afterTrailingSymlink:
if err := child.inode.CheckPermissions(ctx, rp.Credentials(), ats); err != nil {
return nil, err
}
if child.isDir() {
// Can't open directories with O_CREAT.
if opts.Flags&linux.O_CREAT != 0 {
return nil, linuxerr.EISDIR
}
// Can't open directories writably.
if ats&vfs.MayWrite != 0 {
return nil, linuxerr.EISDIR
}
if opts.Flags&linux.O_DIRECT != 0 {
return nil, linuxerr.EINVAL
}
}
// Open may block so we need to unlock fs.mu. IncRef child to prevent
// its destruction while fs.mu is unlocked.
child.IncRef()
+7
View File
@@ -483,10 +483,17 @@ func (d *dentry) open(ctx context.Context, rp *vfs.ResolvingPath, opts *vfs.Open
}
return &fd.vfsfd, nil
case *directory:
// Can't open directories with O_CREAT.
if opts.Flags&linux.O_CREAT != 0 {
return nil, linuxerr.EISDIR
}
// Can't open directories writably.
if ats&vfs.MayWrite != 0 {
return nil, linuxerr.EISDIR
}
if opts.Flags&linux.O_DIRECT != 0 {
return nil, linuxerr.EINVAL
}
var fd directoryFD
fd.LockFD.Init(&d.inode.locks)
if err := fd.vfsfd.Init(&fd, opts.Flags, rp.Mount(), &d.vfsd, &vfs.FileDescriptionOptions{AllowDirectIO: true}); err != nil {
+9 -4
View File
@@ -99,17 +99,17 @@ TEST_F(OpenTest, OCreateDirectory) {
auto dir = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir());
// Normal case: existing directory.
ASSERT_THAT(open(dir.path().c_str(), O_RDWR | O_CREAT, 0666),
ASSERT_THAT(open(dir.path().c_str(), O_RDONLY | O_CREAT, 0666),
SyscallFailsWithErrno(EISDIR));
// Trailing separator on existing directory.
ASSERT_THAT(open(dir.path().append("/").c_str(), O_RDWR | O_CREAT, 0666),
ASSERT_THAT(open(dir.path().append("/").c_str(), O_RDONLY | O_CREAT, 0666),
SyscallFailsWithErrno(EISDIR));
// Trailing separator on non-existing directory.
ASSERT_THAT(open(JoinPath(dir.path(), "non-existent").append("/").c_str(),
O_RDWR | O_CREAT, 0666),
O_RDONLY | O_CREAT, 0666),
SyscallFailsWithErrno(EISDIR));
// "." special case.
ASSERT_THAT(open(JoinPath(dir.path(), ".").c_str(), O_RDWR | O_CREAT, 0666),
ASSERT_THAT(open(JoinPath(dir.path(), ".").c_str(), O_RDONLY | O_CREAT, 0666),
SyscallFailsWithErrno(EISDIR));
}
@@ -399,6 +399,11 @@ TEST_F(OpenTest, DirectoryWritableFails) {
SyscallFailsWithErrno(EISDIR));
}
TEST_F(OpenTest, DirectoryDirectFails) {
ASSERT_THAT(open(GetAbsoluteTestTmpdir().c_str(), O_RDONLY | O_DIRECT),
SyscallFailsWithErrno(EINVAL));
}
TEST_F(OpenTest, FileNotDirectory) {
// Create a file and try to open it with O_DIRECTORY.
auto file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile());