summaryrefslogtreecommitdiffhomepage
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
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
-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