mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
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:
@@ -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
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user