summaryrefslogtreecommitdiffhomepage
path: root/pkg/sentry/fs
diff options
context:
space:
mode:
authorChristopher Koch <chrisko@google.com>2018-05-03 09:59:32 -0700
committerShentubot <shentubot@google.com>2018-05-03 10:00:24 -0700
commit9739b8c21cd1716c4c1c81a27121c50e63fcf906 (patch)
tree8ca7fa9a2294860de43cb03bf45b08b9b7108d03 /pkg/sentry/fs
parent9c665c4c2496f71231f4c60454592854182c0e65 (diff)
Don't prematurely remove MountSource from parent's children.
Otherwise, mounts that fail to be unmounted (EBUSY) will be removed from the children list anyway. At this point, this just affects /proc/pid/mounts and /proc/pid/mountinfo. PiperOrigin-RevId: 195267588 Change-Id: I79114483d73b90f9a7d764a7d513b5b2f251182e
Diffstat (limited to 'pkg/sentry/fs')
-rw-r--r--pkg/sentry/fs/mounts.go46
1 files changed, 22 insertions, 24 deletions
diff --git a/pkg/sentry/fs/mounts.go b/pkg/sentry/fs/mounts.go
index 1e6b5b70e..87da4ee0e 100644
--- a/pkg/sentry/fs/mounts.go
+++ b/pkg/sentry/fs/mounts.go
@@ -272,31 +272,8 @@ func (mns *MountNamespace) Unmount(ctx context.Context, node *Dirent, detachOnly
panic("cannot unmount initial dirent")
}
+ m := node.Inode.MountSource
if !detachOnly {
- m := node.Inode.MountSource
-
- // Lock the parent MountSource first, if it exists. We are
- // holding mns.Lock, so the parent can not change out
- // from under us.
- parent := m.Parent()
- if parent != nil {
- parent.mu.Lock()
- defer parent.mu.Unlock()
- }
-
- // Lock the mount that is being unmounted.
- m.mu.Lock()
- defer m.mu.Unlock()
-
- if m.parent != nil {
- // Sanity check.
- if _, ok := m.parent.children[m]; !ok {
- panic(fmt.Sprintf("mount %+v is not a child of parent %+v", m, m.parent))
- }
- delete(m.parent.children, m)
- m.parent = nil
- }
-
// Flush all references on the mounted node.
m.FlushDirentRefs()
@@ -315,6 +292,27 @@ func (mns *MountNamespace) Unmount(ctx context.Context, node *Dirent, detachOnly
}
}
+ // Lock the parent MountSource first, if it exists. We are
+ // holding mns.Lock, so the parent can not change out
+ // from under us.
+ parent := m.Parent()
+ if parent != nil {
+ parent.mu.Lock()
+ defer parent.mu.Unlock()
+ }
+
+ // Lock the mount that is being unmounted.
+ m.mu.Lock()
+ defer m.mu.Unlock()
+
+ if m.parent != nil {
+ // Sanity check.
+ if _, ok := m.parent.children[m]; !ok {
+ panic(fmt.Sprintf("mount %+v is not a child of parent %+v", m, m.parent))
+ }
+ delete(m.parent.children, m)
+ }
+
original := origs[len(origs)-1]
if err := node.unmount(ctx, original); err != nil {
return err