gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/pkg/sentry/vfs/opath.go (about) 1 // Copyright 2019 The gVisor Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package vfs 16 17 import ( 18 "gvisor.dev/gvisor/pkg/abi/linux" 19 "gvisor.dev/gvisor/pkg/context" 20 "gvisor.dev/gvisor/pkg/errors/linuxerr" 21 "gvisor.dev/gvisor/pkg/sentry/arch" 22 "gvisor.dev/gvisor/pkg/sentry/kernel/auth" 23 "gvisor.dev/gvisor/pkg/sentry/memmap" 24 "gvisor.dev/gvisor/pkg/usermem" 25 ) 26 27 // opathFD implements FileDescriptionImpl for a file description opened with O_PATH. 28 // 29 // +stateify savable 30 type opathFD struct { 31 vfsfd FileDescription 32 FileDescriptionDefaultImpl 33 BadLockFD 34 } 35 36 // Release implements FileDescriptionImpl.Release. 37 func (fd *opathFD) Release(context.Context) { 38 // noop 39 } 40 41 // Allocate implements FileDescriptionImpl.Allocate. 42 func (fd *opathFD) Allocate(ctx context.Context, mode, offset, length uint64) error { 43 return linuxerr.EBADF 44 } 45 46 // PRead implements FileDescriptionImpl.PRead. 47 func (fd *opathFD) PRead(ctx context.Context, dst usermem.IOSequence, offset int64, opts ReadOptions) (int64, error) { 48 return 0, linuxerr.EBADF 49 } 50 51 // Read implements FileDescriptionImpl.Read. 52 func (fd *opathFD) Read(ctx context.Context, dst usermem.IOSequence, opts ReadOptions) (int64, error) { 53 return 0, linuxerr.EBADF 54 } 55 56 // PWrite implements FileDescriptionImpl.PWrite. 57 func (fd *opathFD) PWrite(ctx context.Context, src usermem.IOSequence, offset int64, opts WriteOptions) (int64, error) { 58 return 0, linuxerr.EBADF 59 } 60 61 // Write implements FileDescriptionImpl.Write. 62 func (fd *opathFD) Write(ctx context.Context, src usermem.IOSequence, opts WriteOptions) (int64, error) { 63 return 0, linuxerr.EBADF 64 } 65 66 // Ioctl implements FileDescriptionImpl.Ioctl. 67 func (fd *opathFD) Ioctl(ctx context.Context, uio usermem.IO, sysno uintptr, args arch.SyscallArguments) (uintptr, error) { 68 return 0, linuxerr.EBADF 69 } 70 71 // IterDirents implements FileDescriptionImpl.IterDirents. 72 func (fd *opathFD) IterDirents(ctx context.Context, cb IterDirentsCallback) error { 73 return linuxerr.EBADF 74 } 75 76 // Seek implements FileDescriptionImpl.Seek. 77 func (fd *opathFD) Seek(ctx context.Context, offset int64, whence int32) (int64, error) { 78 return 0, linuxerr.EBADF 79 } 80 81 // ConfigureMMap implements FileDescriptionImpl.ConfigureMMap. 82 func (fd *opathFD) ConfigureMMap(ctx context.Context, opts *memmap.MMapOpts) error { 83 return linuxerr.EBADF 84 } 85 86 // ListXattr implements FileDescriptionImpl.ListXattr. 87 func (fd *opathFD) ListXattr(ctx context.Context, size uint64) ([]string, error) { 88 return nil, linuxerr.EBADF 89 } 90 91 // GetXattr implements FileDescriptionImpl.GetXattr. 92 func (fd *opathFD) GetXattr(ctx context.Context, opts GetXattrOptions) (string, error) { 93 return "", linuxerr.EBADF 94 } 95 96 // SetXattr implements FileDescriptionImpl.SetXattr. 97 func (fd *opathFD) SetXattr(ctx context.Context, opts SetXattrOptions) error { 98 return linuxerr.EBADF 99 } 100 101 // RemoveXattr implements FileDescriptionImpl.RemoveXattr. 102 func (fd *opathFD) RemoveXattr(ctx context.Context, name string) error { 103 return linuxerr.EBADF 104 } 105 106 // Sync implements FileDescriptionImpl.Sync. 107 func (fd *opathFD) Sync(ctx context.Context) error { 108 return linuxerr.EBADF 109 } 110 111 // SetStat implements FileDescriptionImpl.SetStat. 112 func (fd *opathFD) SetStat(ctx context.Context, opts SetStatOptions) error { 113 return linuxerr.EBADF 114 } 115 116 // Stat implements FileDescriptionImpl.Stat. 117 func (fd *opathFD) Stat(ctx context.Context, opts StatOptions) (linux.Statx, error) { 118 vfsObj := fd.vfsfd.vd.mount.vfs 119 rp := vfsObj.getResolvingPath(auth.CredentialsFromContext(ctx), &PathOperation{ 120 Root: fd.vfsfd.vd, 121 Start: fd.vfsfd.vd, 122 }) 123 stat, err := fd.vfsfd.vd.mount.fs.impl.StatAt(ctx, rp, opts) 124 rp.Release(ctx) 125 return stat, err 126 } 127 128 // StatFS returns metadata for the filesystem containing the file represented 129 // by fd. 130 func (fd *opathFD) StatFS(ctx context.Context) (linux.Statfs, error) { 131 vfsObj := fd.vfsfd.vd.mount.vfs 132 rp := vfsObj.getResolvingPath(auth.CredentialsFromContext(ctx), &PathOperation{ 133 Root: fd.vfsfd.vd, 134 Start: fd.vfsfd.vd, 135 }) 136 statfs, err := fd.vfsfd.vd.mount.fs.impl.StatFSAt(ctx, rp) 137 rp.Release(ctx) 138 return statfs, err 139 } 140 141 func (vfs *VirtualFilesystem) openOPathFD(ctx context.Context, creds *auth.Credentials, pop *PathOperation, flags uint32) (*FileDescription, error) { 142 vd, err := vfs.GetDentryAt(ctx, creds, pop, &GetDentryOptions{}) 143 if err != nil { 144 return nil, err 145 } 146 defer vd.DecRef(ctx) 147 148 if flags&linux.O_DIRECTORY != 0 { 149 stat, err := vfs.StatAt(ctx, creds, &PathOperation{ 150 Root: vd, 151 Start: vd, 152 }, &StatOptions{ 153 Mask: linux.STATX_MODE, 154 }) 155 if err != nil { 156 return nil, err 157 } 158 if stat.Mode&linux.S_IFDIR == 0 { 159 return nil, linuxerr.ENOTDIR 160 } 161 } 162 163 fd := &opathFD{} 164 if err := fd.vfsfd.Init(fd, flags, vd.Mount(), vd.Dentry(), &FileDescriptionOptions{}); err != nil { 165 return nil, err 166 } 167 return &fd.vfsfd, err 168 }