Add O_DIRECTORY support to openat(O_PATH) in VFS2.

VFS2 earlier was ignoring the effect of O_DIRECTORY with O_PATH.

PiperOrigin-RevId: 456147699
This commit is contained in:
Ayush Ranjan
2022-06-20 18:43:52 -07:00
committed by gVisor bot
parent c73e953644
commit 9dfac31f0a
3 changed files with 40 additions and 12 deletions
+29
View File
@@ -137,3 +137,32 @@ func (fd *opathFD) StatFS(ctx context.Context) (linux.Statfs, error) {
rp.Release(ctx)
return statfs, err
}
func (vfs *VirtualFilesystem) openOPathFD(ctx context.Context, creds *auth.Credentials, pop *PathOperation, flags uint32) (*FileDescription, error) {
vd, err := vfs.GetDentryAt(ctx, creds, pop, &GetDentryOptions{})
if err != nil {
return nil, err
}
defer vd.DecRef(ctx)
if flags&linux.O_DIRECTORY != 0 {
stat, err := vfs.StatAt(ctx, creds, &PathOperation{
Root: vd,
Start: vd,
}, &StatOptions{
Mask: linux.STATX_MODE,
})
if err != nil {
return nil, err
}
if stat.Mode&linux.S_IFDIR == 0 {
return nil, linuxerr.ENOTDIR
}
}
fd := &opathFD{}
if err := fd.vfsfd.Init(fd, flags, vd.Mount(), vd.Dentry(), &FileDescriptionOptions{}); err != nil {
return nil, err
}
return &fd.vfsfd, err
}
+3 -12
View File
@@ -417,22 +417,13 @@ func (vfs *VirtualFilesystem) OpenAt(ctx context.Context, creds *auth.Credential
if opts.Flags&linux.O_NOFOLLOW != 0 {
pop.FollowFinalSymlink = false
}
if opts.Flags&linux.O_PATH != 0 {
return vfs.openOPathFD(ctx, creds, pop, opts.Flags)
}
rp := vfs.getResolvingPath(creds, pop)
if opts.Flags&linux.O_DIRECTORY != 0 {
rp.mustBeDir = true
}
if opts.Flags&linux.O_PATH != 0 {
vd, err := vfs.GetDentryAt(ctx, creds, pop, &GetDentryOptions{})
if err != nil {
return nil, err
}
fd := &opathFD{}
if err := fd.vfsfd.Init(fd, opts.Flags, vd.Mount(), vd.Dentry(), &FileDescriptionOptions{}); err != nil {
return nil, err
}
vd.DecRef(ctx)
return &fd.vfsfd, err
}
for {
fd, err := rp.mount.fs.impl.OpenAt(ctx, rp, *opts)
if err == nil {
+8
View File
@@ -523,6 +523,14 @@ TEST_F(OpenTest, OpenWithOpath) {
ASSERT_NO_ERRNO(Open(path, O_PATH));
}
// NOTE(b/236445327): Regression test. Opening a non-directory with O_PATH and
// O_DIRECTORY should fail with ENOTDIR.
TEST_F(OpenTest, OPathWithODirectory) {
auto newFile = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile());
EXPECT_THAT(open(newFile.path().c_str(), O_RDONLY | O_DIRECTORY | O_PATH),
SyscallFailsWithErrno(ENOTDIR));
}
} // namespace
} // namespace testing