summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Morozov <lk4d4math@gmail.com>2016-06-13 09:29:46 -0700
committerGitHub <noreply@github.com>2016-06-13 09:29:46 -0700
commit8eb1d89c1755150fef42799f284866ebe604b7dc (patch)
tree71b53f565b543be4d4dd23665fad6b653bb27d64
parent0b879b993df3332814da3c2ae3ba470df84226d2 (diff)
parent7d22887b2c8f4de99c3da7c3a0394ca53fb1c4eb (diff)
downloaddocker-8eb1d89c1755150fef42799f284866ebe604b7dc.tar.gz
Merge pull request #22631 from runcom/fix-leak-mount
pkg: chrootarchive: chroot_linux: fix mount leak
-rw-r--r--pkg/chrootarchive/chroot_linux.go20
1 files changed, 14 insertions, 6 deletions
diff --git a/pkg/chrootarchive/chroot_linux.go b/pkg/chrootarchive/chroot_linux.go
index fb74ee76bf..cefbef9df4 100644
--- a/pkg/chrootarchive/chroot_linux.go
+++ b/pkg/chrootarchive/chroot_linux.go
@@ -6,6 +6,8 @@ import (
"os"
"path/filepath"
"syscall"
+
+ "github.com/docker/docker/pkg/mount"
)
// chroot on linux uses pivot_root instead of chroot
@@ -15,13 +17,12 @@ import (
// Old root is removed after the call to pivot_root so it is no longer available under the new root.
// This is similar to how libcontainer sets up a container's rootfs
func chroot(path string) (err error) {
- // Create new mount namespace so mounts don't leak
if err := syscall.Unshare(syscall.CLONE_NEWNS); err != nil {
return fmt.Errorf("Error creating mount namespace before pivot: %v", err)
}
- // path must be a different fs for pivot_root, so bind-mount to itself to ensure this
- if err := syscall.Mount(path, path, "", syscall.MS_BIND, ""); err != nil {
- return fmt.Errorf("Error mounting pivot dir before pivot: %v", err)
+
+ if err := mount.MakeRPrivate(path); err != nil {
+ return err
}
// setup oldRoot for pivot_root
@@ -44,17 +45,24 @@ func chroot(path string) (err error) {
errCleanup := os.Remove(pivotDir)
// pivotDir doesn't exist if pivot_root failed and chroot+chdir was successful
- // but we already cleaned it up on failed pivot_root
+ // because we already cleaned it up on failed pivot_root
if errCleanup != nil && !os.IsNotExist(errCleanup) {
errCleanup = fmt.Errorf("Error cleaning up after pivot: %v", errCleanup)
if err == nil {
err = errCleanup
}
}
+
+ if errCleanup := syscall.Unmount("/", syscall.MNT_DETACH); errCleanup != nil {
+ if err == nil {
+ err = fmt.Errorf("error unmounting root: %v", errCleanup)
+ }
+ return
+ }
}()
if err := syscall.PivotRoot(path, pivotDir); err != nil {
- // If pivot fails, fall back to the normal chroot after cleaning up temp dir for pivot_root
+ // If pivot fails, fall back to the normal chroot after cleaning up temp dir
if err := os.Remove(pivotDir); err != nil {
return fmt.Errorf("Error cleaning up after failed pivot: %v", err)
}