diff options
author | Alexander Morozov <lk4d4math@gmail.com> | 2016-06-13 09:29:46 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-06-13 09:29:46 -0700 |
commit | 8eb1d89c1755150fef42799f284866ebe604b7dc (patch) | |
tree | 71b53f565b543be4d4dd23665fad6b653bb27d64 | |
parent | 0b879b993df3332814da3c2ae3ba470df84226d2 (diff) | |
parent | 7d22887b2c8f4de99c3da7c3a0394ca53fb1c4eb (diff) | |
download | docker-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.go | 20 |
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) } |