diff options
author | Jamie Liu <jamieliu@google.com> | 2020-04-06 16:31:27 -0700 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2020-04-06 16:32:37 -0700 |
commit | dd98fdd5beb7f02e7c7b3aeb4f07f5d00ffc41e7 (patch) | |
tree | e6283145cf7bfba07af15b98681eec219948f6bf /pkg/sentry/fsimpl/kernfs/filesystem.go | |
parent | f332a864e8cc7799332838deffab37244ff8ffc7 (diff) |
Correctly implement magic symlinks in VFS2 procfs.
Updates #1195
PiperOrigin-RevId: 305143567
Diffstat (limited to 'pkg/sentry/fsimpl/kernfs/filesystem.go')
-rw-r--r-- | pkg/sentry/fsimpl/kernfs/filesystem.go | 36 |
1 files changed, 24 insertions, 12 deletions
diff --git a/pkg/sentry/fsimpl/kernfs/filesystem.go b/pkg/sentry/fsimpl/kernfs/filesystem.go index 89f5da3d4..16a3c18ae 100644 --- a/pkg/sentry/fsimpl/kernfs/filesystem.go +++ b/pkg/sentry/fsimpl/kernfs/filesystem.go @@ -79,16 +79,22 @@ afterSymlink: } // Resolve any symlink at current path component. if rp.ShouldFollowSymlink() && next.isSymlink() { - // TODO: VFS2 needs something extra for /proc/[pid]/fd/ "magic symlinks". - target, err := next.inode.Readlink(ctx) + targetVD, targetPathname, err := next.inode.Getlink(ctx) if err != nil { return nil, err } - if err := rp.HandleSymlink(target); err != nil { - return nil, err + if targetVD.Ok() { + err := rp.HandleJump(targetVD) + targetVD.DecRef() + if err != nil { + return nil, err + } + } else { + if err := rp.HandleSymlink(targetPathname); err != nil { + return nil, err + } } goto afterSymlink - } rp.Advance() return &next.vfsd, nil @@ -470,19 +476,25 @@ afterTrailingSymlink: } childDentry := childVFSD.Impl().(*Dentry) childInode := childDentry.inode - if rp.ShouldFollowSymlink() { - if childDentry.isSymlink() { - target, err := childInode.Readlink(ctx) + if rp.ShouldFollowSymlink() && childDentry.isSymlink() { + targetVD, targetPathname, err := childInode.Getlink(ctx) + if err != nil { + return nil, err + } + if targetVD.Ok() { + err := rp.HandleJump(targetVD) + targetVD.DecRef() if err != nil { return nil, err } - if err := rp.HandleSymlink(target); err != nil { + } else { + if err := rp.HandleSymlink(targetPathname); err != nil { return nil, err } - // rp.Final() may no longer be true since we now need to resolve the - // symlink target. - goto afterTrailingSymlink } + // rp.Final() may no longer be true since we now need to resolve the + // symlink target. + goto afterTrailingSymlink } if err := childInode.CheckPermissions(ctx, rp.Credentials(), ats); err != nil { return nil, err |