Merge pull request #40970 from AkihiroSuda/archive-40939-1903

[19.03 backport] pkg/archive: escape ":" symbol in overlay lowerdir
diff --git a/pkg/archive/archive_linux.go b/pkg/archive/archive_linux.go
index 0601f7b..c0f81ac 100644
--- a/pkg/archive/archive_linux.go
+++ b/pkg/archive/archive_linux.go
@@ -151,7 +151,9 @@
 	if err := ioutil.WriteFile(lowerDummy, []byte{}, 0600); err != nil {
 		return errors.Wrapf(err, "failed to create a dummy lower file %s", lowerDummy)
 	}
-	mOpts := fmt.Sprintf("lowerdir=%s,upperdir=%s,workdir=%s", lower, upper, work)
+	// lowerdir needs ":" to be escaped: https://github.com/moby/moby/issues/40939#issuecomment-627098286
+	lowerEscaped := strings.ReplaceAll(lower, ":", "\\:")
+	mOpts := fmt.Sprintf("lowerdir=%s,upperdir=%s,workdir=%s", lowerEscaped, upper, work)
 	// docker/pkg/mount.Mount() requires procfs to be mounted. So we use syscall.Mount() directly instead.
 	if err := syscall.Mount("overlay", merged, "overlay", uintptr(0), mOpts); err != nil {
 		return errors.Wrapf(err, "failed to mount overlay (%s) on %s", mOpts, merged)
@@ -236,7 +238,9 @@
 	if err := os.MkdirAll(lowerDummy, 0700); err != nil {
 		return "", errors.Wrapf(err, "failed to create a dummy lower directory %s", lowerDummy)
 	}
-	mOpts := fmt.Sprintf("lowerdir=%s,upperdir=%s,workdir=%s", lower, upper, work)
+	// lowerdir needs ":" to be escaped: https://github.com/moby/moby/issues/40939#issuecomment-627098286
+	lowerEscaped := strings.ReplaceAll(lower, ":", "\\:")
+	mOpts := fmt.Sprintf("lowerdir=%s,upperdir=%s,workdir=%s", lowerEscaped, upper, work)
 	// docker/pkg/mount.Mount() requires procfs to be mounted. So we use syscall.Mount() directly instead.
 	if err := syscall.Mount("overlay", merged, "overlay", uintptr(0), mOpts); err != nil {
 		return "", errors.Wrapf(err, "failed to mount overlay (%s) on %s", mOpts, merged)