diff options
author | gVisor bot <gvisor-bot@google.com> | 2020-03-28 00:02:06 +0000 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2020-03-28 00:02:06 +0000 |
commit | c52860cb85f5b5158a7ab8ae17df1c5f5eca6792 (patch) | |
tree | 2cbe0a631d87b09cfb92195d54e7e78542cdfd58 /pkg/sentry/vfs/pathname.go | |
parent | a6ea548493fda77685d10293a0380b37bee93617 (diff) | |
parent | f6e4daa67ad5f07ac1bcff33476b4d13f49a69bc (diff) |
Merge release-20200219.0-255-gf6e4daa (automated)
Diffstat (limited to 'pkg/sentry/vfs/pathname.go')
-rwxr-xr-x | pkg/sentry/vfs/pathname.go | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/pkg/sentry/vfs/pathname.go b/pkg/sentry/vfs/pathname.go index b318c681a..f21a88034 100755 --- a/pkg/sentry/vfs/pathname.go +++ b/pkg/sentry/vfs/pathname.go @@ -90,6 +90,49 @@ loop: return b.String(), nil } +// PathnameReachable returns an absolute pathname to vd, consistent with +// Linux's __d_path() (as used by seq_path_root()). If vfsroot.Ok() and vd is +// not reachable from vfsroot, such that seq_path_root() would return SEQ_SKIP +// (causing the entire containing entry to be skipped), PathnameReachable +// returns ("", nil). +func (vfs *VirtualFilesystem) PathnameReachable(ctx context.Context, vfsroot, vd VirtualDentry) (string, error) { + b := getFSPathBuilder() + defer putFSPathBuilder(b) + haveRef := false + defer func() { + if haveRef { + vd.DecRef() + } + }() +loop: + for { + err := vd.mount.fs.impl.PrependPath(ctx, vfsroot, vd, b) + switch err.(type) { + case nil: + if vd.mount == vfsroot.mount && vd.mount.root == vfsroot.dentry { + break loop + } + nextVD := vfs.getMountpointAt(vd.mount, vfsroot) + if !nextVD.Ok() { + return "", nil + } + if haveRef { + vd.DecRef() + } + vd = nextVD + haveRef = true + case PrependPathAtVFSRootError: + break loop + case PrependPathAtNonMountRootError, PrependPathSyntheticError: + return "", nil + default: + return "", err + } + } + b.PrependByte('/') + return b.String(), nil +} + // PathnameForGetcwd returns an absolute pathname to vd, consistent with // Linux's sys_getcwd(). func (vfs *VirtualFilesystem) PathnameForGetcwd(ctx context.Context, vfsroot, vd VirtualDentry) (string, error) { |