diff options
author | Fabricio Voznika <fvoznika@google.com> | 2020-04-24 11:43:49 -0700 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2020-04-24 11:45:19 -0700 |
commit | 2cc0fd42f462f3942230c4b33ca2825e2a28765d (patch) | |
tree | 0da2fde5d7f23d3faf28c0a5a086d8832a09e0f8 /pkg/sentry/fsimpl/kernfs | |
parent | 1b88c63b3e6b330c8399bf92f148cc80374bee18 (diff) |
Fixes for procfs
- Return ENOENT for /proc/[pid]/task if task is zoombied or terminated
- Allow directory to be Seek() to the end
- Construct synthetic files for /proc/[pid]/ns/*
- Changed GenericDirectoryFD.Init to not register with FileDescription,
otherwise other implementation cannot change behavior.
Updates #1195,1193
PiperOrigin-RevId: 308294649
Diffstat (limited to 'pkg/sentry/fsimpl/kernfs')
-rw-r--r-- | pkg/sentry/fsimpl/kernfs/fd_impl_util.go | 28 | ||||
-rw-r--r-- | pkg/sentry/fsimpl/kernfs/filesystem.go | 4 | ||||
-rw-r--r-- | pkg/sentry/fsimpl/kernfs/inode_impl_util.go | 8 | ||||
-rw-r--r-- | pkg/sentry/fsimpl/kernfs/kernfs.go | 2 | ||||
-rw-r--r-- | pkg/sentry/fsimpl/kernfs/kernfs_test.go | 10 | ||||
-rw-r--r-- | pkg/sentry/fsimpl/kernfs/symlink.go | 2 |
6 files changed, 38 insertions, 16 deletions
diff --git a/pkg/sentry/fsimpl/kernfs/fd_impl_util.go b/pkg/sentry/fsimpl/kernfs/fd_impl_util.go index e8a4670b8..dd5806301 100644 --- a/pkg/sentry/fsimpl/kernfs/fd_impl_util.go +++ b/pkg/sentry/fsimpl/kernfs/fd_impl_util.go @@ -15,6 +15,8 @@ package kernfs import ( + "math" + "gvisor.dev/gvisor/pkg/abi/linux" "gvisor.dev/gvisor/pkg/context" "gvisor.dev/gvisor/pkg/sentry/kernel/auth" @@ -43,15 +45,27 @@ type GenericDirectoryFD struct { off int64 } -// Init initializes a GenericDirectoryFD. -func (fd *GenericDirectoryFD) Init(m *vfs.Mount, d *vfs.Dentry, children *OrderedChildren, opts *vfs.OpenOptions) error { +// NewGenericDirectoryFD creates a new GenericDirectoryFD and returns its +// dentry. +func NewGenericDirectoryFD(m *vfs.Mount, d *vfs.Dentry, children *OrderedChildren, opts *vfs.OpenOptions) (*GenericDirectoryFD, error) { + fd := &GenericDirectoryFD{} + if err := fd.Init(children, opts); err != nil { + return nil, err + } + if err := fd.vfsfd.Init(fd, opts.Flags, m, d, &vfs.FileDescriptionOptions{}); err != nil { + return nil, err + } + return fd, nil +} + +// Init initializes a GenericDirectoryFD. Use it when overriding +// GenericDirectoryFD. Caller must call fd.VFSFileDescription.Init() with the +// correct implementation. +func (fd *GenericDirectoryFD) Init(children *OrderedChildren, opts *vfs.OpenOptions) error { if vfs.AccessTypesForOpenFlags(opts)&vfs.MayWrite != 0 { // Can't open directories for writing. return syserror.EISDIR } - if err := fd.vfsfd.Init(fd, opts.Flags, m, d, &vfs.FileDescriptionOptions{}); err != nil { - return err - } fd.children = children return nil } @@ -187,6 +201,10 @@ func (fd *GenericDirectoryFD) Seek(ctx context.Context, offset int64, whence int // Use offset as given. case linux.SEEK_CUR: offset += fd.off + case linux.SEEK_END: + // TODO(gvisor.dev/issue/1193): This can prevent new files from showing up + // if they are added after SEEK_END. + offset = math.MaxInt64 default: return 0, syserror.EINVAL } diff --git a/pkg/sentry/fsimpl/kernfs/filesystem.go b/pkg/sentry/fsimpl/kernfs/filesystem.go index 1d46dba25..3ccd92fc5 100644 --- a/pkg/sentry/fsimpl/kernfs/filesystem.go +++ b/pkg/sentry/fsimpl/kernfs/filesystem.go @@ -82,7 +82,7 @@ afterSymlink: } // Resolve any symlink at current path component. if rp.ShouldFollowSymlink() && next.isSymlink() { - targetVD, targetPathname, err := next.inode.Getlink(ctx) + targetVD, targetPathname, err := next.inode.Getlink(ctx, rp.Mount()) if err != nil { return nil, err } @@ -477,7 +477,7 @@ afterTrailingSymlink: } child := childVFSD.Impl().(*Dentry) if rp.ShouldFollowSymlink() && child.isSymlink() { - targetVD, targetPathname, err := child.inode.Getlink(ctx) + targetVD, targetPathname, err := child.inode.Getlink(ctx, rp.Mount()) if err != nil { return nil, err } diff --git a/pkg/sentry/fsimpl/kernfs/inode_impl_util.go b/pkg/sentry/fsimpl/kernfs/inode_impl_util.go index a946645f6..02f35a675 100644 --- a/pkg/sentry/fsimpl/kernfs/inode_impl_util.go +++ b/pkg/sentry/fsimpl/kernfs/inode_impl_util.go @@ -182,7 +182,7 @@ func (InodeNotSymlink) Readlink(context.Context) (string, error) { } // Getlink implements Inode.Getlink. -func (InodeNotSymlink) Getlink(context.Context) (vfs.VirtualDentry, string, error) { +func (InodeNotSymlink) Getlink(context.Context, *vfs.Mount) (vfs.VirtualDentry, string, error) { return vfs.VirtualDentry{}, "", syserror.EINVAL } @@ -568,8 +568,10 @@ func (s *StaticDirectory) Init(creds *auth.Credentials, ino uint64, perm linux.F // Open implements kernfs.Inode. func (s *StaticDirectory) Open(rp *vfs.ResolvingPath, vfsd *vfs.Dentry, opts vfs.OpenOptions) (*vfs.FileDescription, error) { - fd := &GenericDirectoryFD{} - fd.Init(rp.Mount(), vfsd, &s.OrderedChildren, &opts) + fd, err := NewGenericDirectoryFD(rp.Mount(), vfsd, &s.OrderedChildren, &opts) + if err != nil { + return nil, err + } return fd.VFSFileDescription(), nil } diff --git a/pkg/sentry/fsimpl/kernfs/kernfs.go b/pkg/sentry/fsimpl/kernfs/kernfs.go index f5041824f..95cf6dc24 100644 --- a/pkg/sentry/fsimpl/kernfs/kernfs.go +++ b/pkg/sentry/fsimpl/kernfs/kernfs.go @@ -439,5 +439,5 @@ type inodeSymlink interface { // // - If the inode is not a symlink, Getlink returns (zero-value // VirtualDentry, "", EINVAL). - Getlink(ctx context.Context) (vfs.VirtualDentry, string, error) + Getlink(ctx context.Context, mnt *vfs.Mount) (vfs.VirtualDentry, string, error) } diff --git a/pkg/sentry/fsimpl/kernfs/kernfs_test.go b/pkg/sentry/fsimpl/kernfs/kernfs_test.go index 465451f35..0964d5456 100644 --- a/pkg/sentry/fsimpl/kernfs/kernfs_test.go +++ b/pkg/sentry/fsimpl/kernfs/kernfs_test.go @@ -117,8 +117,8 @@ func (fs *filesystem) newReadonlyDir(creds *auth.Credentials, mode linux.FileMod } func (d *readonlyDir) Open(rp *vfs.ResolvingPath, vfsd *vfs.Dentry, opts vfs.OpenOptions) (*vfs.FileDescription, error) { - fd := &kernfs.GenericDirectoryFD{} - if err := fd.Init(rp.Mount(), vfsd, &d.OrderedChildren, &opts); err != nil { + fd, err := kernfs.NewGenericDirectoryFD(rp.Mount(), vfsd, &d.OrderedChildren, &opts) + if err != nil { return nil, err } return fd.VFSFileDescription(), nil @@ -147,8 +147,10 @@ func (fs *filesystem) newDir(creds *auth.Credentials, mode linux.FileMode, conte } func (d *dir) Open(rp *vfs.ResolvingPath, vfsd *vfs.Dentry, opts vfs.OpenOptions) (*vfs.FileDescription, error) { - fd := &kernfs.GenericDirectoryFD{} - fd.Init(rp.Mount(), vfsd, &d.OrderedChildren, &opts) + fd, err := kernfs.NewGenericDirectoryFD(rp.Mount(), vfsd, &d.OrderedChildren, &opts) + if err != nil { + return nil, err + } return fd.VFSFileDescription(), nil } diff --git a/pkg/sentry/fsimpl/kernfs/symlink.go b/pkg/sentry/fsimpl/kernfs/symlink.go index 018aa503c..0aa6dc979 100644 --- a/pkg/sentry/fsimpl/kernfs/symlink.go +++ b/pkg/sentry/fsimpl/kernfs/symlink.go @@ -56,7 +56,7 @@ func (s *StaticSymlink) Readlink(_ context.Context) (string, error) { } // Getlink implements Inode.Getlink. -func (s *StaticSymlink) Getlink(_ context.Context) (vfs.VirtualDentry, string, error) { +func (s *StaticSymlink) Getlink(context.Context, *vfs.Mount) (vfs.VirtualDentry, string, error) { return vfs.VirtualDentry{}, s.target, nil } |