diff options
author | Dean Deng <deandeng@google.com> | 2020-06-19 05:55:35 -0700 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2020-06-19 05:57:15 -0700 |
commit | 46957ed24f21396683cf9aff13fa0cd3086ea466 (patch) | |
tree | dab832441b05aae016fe320f0b5b2f51a7457870 /pkg/sentry/fsimpl/gofer/filesystem.go | |
parent | 408f3d2cd64cae6b2f76a940c76236e9841c095f (diff) |
Fix synthetic file bugs in gofer fs.
Always check if a synthetic file already exists at a location before creating a
file there, and do not try to delete synthetic gofer files from the remote fs.
This fixes runsc_ptrace socket tests that create/unlink synthetic, named socket
files.
Updates #2923.
PiperOrigin-RevId: 317293648
Diffstat (limited to 'pkg/sentry/fsimpl/gofer/filesystem.go')
-rw-r--r-- | pkg/sentry/fsimpl/gofer/filesystem.go | 19 |
1 files changed, 11 insertions, 8 deletions
diff --git a/pkg/sentry/fsimpl/gofer/filesystem.go b/pkg/sentry/fsimpl/gofer/filesystem.go index 3c467e313..21eb976cb 100644 --- a/pkg/sentry/fsimpl/gofer/filesystem.go +++ b/pkg/sentry/fsimpl/gofer/filesystem.go @@ -374,13 +374,16 @@ func (fs *filesystem) doCreateAt(ctx context.Context, rp *vfs.ResolvingPath, dir return nil } if fs.opts.interop == InteropModeShared { - // The existence of a dentry at name would be inconclusive because the - // file it represents may have been deleted from the remote filesystem, - // so we would need to make an RPC to revalidate the dentry. Just - // attempt the file creation RPC instead. If a file does exist, the RPC - // will fail with EEXIST like we would have. If the RPC succeeds, and a - // stale dentry exists, the dentry will fail revalidation next time - // it's used. + if child := parent.children[name]; child != nil && child.isSynthetic() { + return syserror.EEXIST + } + // The existence of a non-synthetic dentry at name would be inconclusive + // because the file it represents may have been deleted from the remote + // filesystem, so we would need to make an RPC to revalidate the dentry. + // Just attempt the file creation RPC instead. If a file does exist, the + // RPC will fail with EEXIST like we would have. If the RPC succeeds, and a + // stale dentry exists, the dentry will fail revalidation next time it's + // used. return createInRemoteDir(parent, name) } if child := parent.children[name]; child != nil { @@ -518,7 +521,7 @@ func (fs *filesystem) unlinkAt(ctx context.Context, rp *vfs.ResolvingPath, dir b if child == nil { return syserror.ENOENT } - } else { + } else if child == nil || !child.isSynthetic() { err = parent.file.unlinkAt(ctx, name, flags) if err != nil { if child != nil { |