summaryrefslogtreecommitdiffhomepage
path: root/pkg/sentry/fsimpl
diff options
context:
space:
mode:
authorFabricio Voznika <fvoznika@google.com>2019-12-23 17:31:20 -0800
committergVisor bot <gvisor-bot@google.com>2019-12-23 17:32:46 -0800
commit574e988f2bc6060078a17f37a377441703c52a22 (patch)
treec6742e6155cfcce99ada46b09800c30c7d79263e /pkg/sentry/fsimpl
parentf45df7505b0e7baf48a37f7c625f05051d144738 (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')
-rw-r--r--pkg/sentry/fsimpl/kernfs/filesystem.go2
-rw-r--r--pkg/sentry/fsimpl/kernfs/kernfs.go12
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