diff options
author | gVisor bot <gvisor-bot@google.com> | 2021-04-29 23:16:22 +0000 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2021-04-29 23:16:22 +0000 |
commit | 3d0e241a796310b95f6200238687f8bf6d0dc23b (patch) | |
tree | 66328459ba711f165a7449f4b4f7c5e3fd24b6f1 | |
parent | 8c0d3f7623b1b2a5c023db6a6f8c4e1e686cccb9 (diff) | |
parent | 9ff0d382d69c53a8fc916cfde844f1e657759f59 (diff) |
Merge release-20210419.0-45-g9ff0d382d (automated)
-rw-r--r-- | pkg/sentry/fsimpl/gofer/filesystem.go | 29 |
1 files changed, 24 insertions, 5 deletions
diff --git a/pkg/sentry/fsimpl/gofer/filesystem.go b/pkg/sentry/fsimpl/gofer/filesystem.go index 40c9243f0..c1c9ec008 100644 --- a/pkg/sentry/fsimpl/gofer/filesystem.go +++ b/pkg/sentry/fsimpl/gofer/filesystem.go @@ -364,21 +364,40 @@ func (fs *filesystem) doCreateAt(ctx context.Context, rp *vfs.ResolvingPath, dir parent.dirMu.Lock() defer parent.dirMu.Unlock() - child, err := fs.getChildLocked(ctx, parent, name, &ds) - switch { - case err != nil && err != syserror.ENOENT: - return err - case child != nil: + if len(name) > maxFilenameLen { + return syserror.ENAMETOOLONG + } + // Check for existence only if caching information is available. Otherwise, + // don't check for existence just yet. We will check for existence if the + // checks for writability fail below. Existence check is done by the creation + // RPCs themselves. + if child, ok := parent.children[name]; ok && child != nil { return syserror.EEXIST } + checkExistence := func() error { + if child, err := fs.getChildLocked(ctx, parent, name, &ds); err != nil && err != syserror.ENOENT { + return err + } else if child != nil { + return syserror.EEXIST + } + return nil + } mnt := rp.Mount() if err := mnt.CheckBeginWrite(); err != nil { + // Existence check takes precedence. + if existenceErr := checkExistence(); existenceErr != nil { + return existenceErr + } return err } defer mnt.EndWrite() if err := parent.checkPermissions(rp.Credentials(), vfs.MayWrite); err != nil { + // Existence check takes precedence. + if existenceErr := checkExistence(); existenceErr != nil { + return existenceErr + } return err } if !dir && rp.MustBeDir() { |