summaryrefslogtreecommitdiffhomepage
path: root/pkg/sentry/fsimpl/overlay/filesystem.go
diff options
context:
space:
mode:
authorJamie Liu <jamieliu@google.com>2020-08-18 14:34:15 -0700
committergVisor bot <gvisor-bot@google.com>2020-08-18 14:36:06 -0700
commit6405525b046bb82a39e3338e61e41690133c43c1 (patch)
treeed81e45d60f4c2801c1c979baef74f54ef1b2d74 /pkg/sentry/fsimpl/overlay/filesystem.go
parent760c131da17250b6adbb8d08dd52e9a3d652b2c1 (diff)
Avoid holding locks when opening files in VFS2.
Fixes #3243, #3521 PiperOrigin-RevId: 327308890
Diffstat (limited to 'pkg/sentry/fsimpl/overlay/filesystem.go')
-rw-r--r--pkg/sentry/fsimpl/overlay/filesystem.go42
1 files changed, 31 insertions, 11 deletions
diff --git a/pkg/sentry/fsimpl/overlay/filesystem.go b/pkg/sentry/fsimpl/overlay/filesystem.go
index 986b36ead..86d0164b4 100644
--- a/pkg/sentry/fsimpl/overlay/filesystem.go
+++ b/pkg/sentry/fsimpl/overlay/filesystem.go
@@ -717,17 +717,33 @@ func (fs *filesystem) MknodAt(ctx context.Context, rp *vfs.ResolvingPath, opts v
func (fs *filesystem) OpenAt(ctx context.Context, rp *vfs.ResolvingPath, opts vfs.OpenOptions) (*vfs.FileDescription, error) {
mayCreate := opts.Flags&linux.O_CREAT != 0
mustCreate := opts.Flags&(linux.O_CREAT|linux.O_EXCL) == (linux.O_CREAT | linux.O_EXCL)
+ mayWrite := vfs.AccessTypesForOpenFlags(&opts).MayWrite()
var ds *[]*dentry
fs.renameMu.RLock()
- defer fs.renameMuRUnlockAndCheckDrop(ctx, &ds)
+ unlocked := false
+ unlock := func() {
+ if !unlocked {
+ fs.renameMuRUnlockAndCheckDrop(ctx, &ds)
+ unlocked = true
+ }
+ }
+ defer unlock()
start := rp.Start().Impl().(*dentry)
if rp.Done() {
if mustCreate {
return nil, syserror.EEXIST
}
- return start.openLocked(ctx, rp, &opts)
+ if mayWrite {
+ if err := start.copyUpLocked(ctx); err != nil {
+ return nil, err
+ }
+ }
+ start.IncRef()
+ defer start.DecRef(ctx)
+ unlock()
+ return start.openCopiedUp(ctx, rp, &opts)
}
afterTrailingSymlink:
@@ -767,20 +783,24 @@ afterTrailingSymlink:
start = parent
goto afterTrailingSymlink
}
- return child.openLocked(ctx, rp, &opts)
+ if mayWrite {
+ if err := child.copyUpLocked(ctx); err != nil {
+ return nil, err
+ }
+ }
+ child.IncRef()
+ defer child.DecRef(ctx)
+ unlock()
+ return child.openCopiedUp(ctx, rp, &opts)
}
-// Preconditions: fs.renameMu must be locked.
-func (d *dentry) openLocked(ctx context.Context, rp *vfs.ResolvingPath, opts *vfs.OpenOptions) (*vfs.FileDescription, error) {
+// Preconditions: If vfs.AccessTypesForOpenFlags(opts).MayWrite(), then d has
+// been copied up.
+func (d *dentry) openCopiedUp(ctx context.Context, rp *vfs.ResolvingPath, opts *vfs.OpenOptions) (*vfs.FileDescription, error) {
ats := vfs.AccessTypesForOpenFlags(opts)
if err := d.checkPermissions(rp.Credentials(), ats); err != nil {
return nil, err
}
- if ats.MayWrite() {
- if err := d.copyUpLocked(ctx); err != nil {
- return nil, err
- }
- }
mnt := rp.Mount()
// Directory FDs open FDs from each layer when directory entries are read,
@@ -792,7 +812,7 @@ func (d *dentry) openLocked(ctx context.Context, rp *vfs.ResolvingPath, opts *vf
return nil, syserror.EISDIR
}
// Can't open directories writably.
- if ats&vfs.MayWrite != 0 {
+ if ats.MayWrite() {
return nil, syserror.EISDIR
}
if opts.Flags&linux.O_DIRECT != 0 {