diff options
author | Fabricio Voznika <fvoznika@google.com> | 2019-12-23 17:31:20 -0800 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2019-12-23 17:32:46 -0800 |
commit | 574e988f2bc6060078a17f37a377441703c52a22 (patch) | |
tree | c6742e6155cfcce99ada46b09800c30c7d79263e /pkg/sentry/fsimpl/kernfs | |
parent | f45df7505b0e7baf48a37f7c625f05051d144738 (diff) |
Fix deadlock in kernfs.Filesystem.revalidateChildLocked
It was calling Dentry.InsertChild with the dentry's mutex
already locked.
Updates #1035
PiperOrigin-RevId: 286962742
Diffstat (limited to 'pkg/sentry/fsimpl/kernfs')
-rw-r--r-- | pkg/sentry/fsimpl/kernfs/filesystem.go | 2 | ||||
-rw-r--r-- | pkg/sentry/fsimpl/kernfs/kernfs.go | 12 |
2 files changed, 11 insertions, 3 deletions
diff --git a/pkg/sentry/fsimpl/kernfs/filesystem.go b/pkg/sentry/fsimpl/kernfs/filesystem.go index a6f9fced5..79759e0fc 100644 --- a/pkg/sentry/fsimpl/kernfs/filesystem.go +++ b/pkg/sentry/fsimpl/kernfs/filesystem.go @@ -122,7 +122,7 @@ func (fs *Filesystem) revalidateChildLocked(ctx context.Context, vfsObj *vfs.Vir return nil, err } // Reference on childVFSD dropped by a corresponding Valid. - parent.InsertChild(name, childVFSD) + parent.insertChildLocked(name, childVFSD) } return childVFSD.Impl().(*Dentry), nil } diff --git a/pkg/sentry/fsimpl/kernfs/kernfs.go b/pkg/sentry/fsimpl/kernfs/kernfs.go index bb01c3d01..ac802218d 100644 --- a/pkg/sentry/fsimpl/kernfs/kernfs.go +++ b/pkg/sentry/fsimpl/kernfs/kernfs.go @@ -239,14 +239,22 @@ func (d *Dentry) destroy() { // // Precondition: d must represent a directory inode. func (d *Dentry) InsertChild(name string, child *vfs.Dentry) { + d.dirMu.Lock() + d.insertChildLocked(name, child) + d.dirMu.Unlock() +} + +// insertChildLocked is equivalent to InsertChild, with additional +// preconditions. +// +// Precondition: d.dirMu must be locked. +func (d *Dentry) insertChildLocked(name string, child *vfs.Dentry) { if !d.isDir() { panic(fmt.Sprintf("InsertChild called on non-directory Dentry: %+v.", d)) } vfsDentry := d.VFSDentry() vfsDentry.IncRef() // DecRef in child's Dentry.destroy. - d.dirMu.Lock() vfsDentry.InsertChild(child, name) - d.dirMu.Unlock() } // The Inode interface maps filesystem-level operations that operate on paths to |