瀏覽代碼

validate mount path for tmpfs

There was no validation for `docker run --tmpfs foo`.

In this PR, only two obvious rules are implemented:
 - path must be absolute
 - path must not be "/"
We should add more rules carefully.

Signed-off-by: Akihiro Suda <suda.akihiro@lab.ntt.co.jp>
Akihiro Suda 8 年之前
父節點
當前提交
4a8799dc0a
共有 3 個文件被更改,包括 65 次插入0 次删除
  1. 7 0
      daemon/daemon_unix.go
  2. 43 0
      integration-cli/docker_cli_create_unix_test.go
  3. 15 0
      volume/validate.go

+ 7 - 0
daemon/daemon_unix.go

@@ -29,6 +29,7 @@ import (
 	"github.com/docker/docker/pkg/parsers/kernel"
 	"github.com/docker/docker/pkg/sysinfo"
 	"github.com/docker/docker/runconfig"
+	"github.com/docker/docker/volume"
 	"github.com/docker/libnetwork"
 	nwconfig "github.com/docker/libnetwork/config"
 	"github.com/docker/libnetwork/drivers/bridge"
@@ -553,6 +554,12 @@ func verifyPlatformContainerSettings(daemon *Daemon, hostConfig *containertypes.
 		return warnings, fmt.Errorf("Unknown runtime specified %s", hostConfig.Runtime)
 	}
 
+	for dest := range hostConfig.Tmpfs {
+		if err := volume.ValidateTmpfsMountDestination(dest); err != nil {
+			return warnings, err
+		}
+	}
+
 	return warnings, nil
 }
 

+ 43 - 0
integration-cli/docker_cli_create_unix_test.go

@@ -0,0 +1,43 @@
+// +build !windows
+
+package main
+
+import (
+	"strings"
+
+	"github.com/go-check/check"
+)
+
+// Test case for #30166 (target was not validated)
+func (s *DockerSuite) TestCreateTmpfsMountsTarget(c *check.C) {
+	testRequires(c, DaemonIsLinux)
+	type testCase struct {
+		target        string
+		expectedError string
+	}
+	cases := []testCase{
+		{
+			target:        ".",
+			expectedError: "mount path must be absolute",
+		},
+		{
+			target:        "foo",
+			expectedError: "mount path must be absolute",
+		},
+		{
+			target:        "/",
+			expectedError: "destination can't be '/'",
+		},
+		{
+			target:        "//",
+			expectedError: "destination can't be '/'",
+		},
+	}
+	for _, x := range cases {
+		out, _, _ := dockerCmdWithError("create", "--tmpfs", x.target, "busybox", "sh")
+		if x.expectedError != "" && !strings.Contains(out, x.expectedError) {
+			c.Fatalf("mounting tmpfs over %q should fail with %q, but got %q",
+				x.target, x.expectedError, out)
+		}
+	}
+}

+ 15 - 0
volume/validate.go

@@ -91,6 +91,9 @@ func validateMountConfig(mnt *mount.Mount, options ...func(*validateOpts)) error
 		if len(mnt.Source) != 0 {
 			return &errMountConfig{mnt, errExtraField("Source")}
 		}
+		if err := ValidateTmpfsMountDestination(mnt.Target); err != nil {
+			return &errMountConfig{mnt, err}
+		}
 		if _, err := ConvertTmpfsOptions(mnt.TmpfsOptions, mnt.ReadOnly); err != nil {
 			return &errMountConfig{mnt, err}
 		}
@@ -123,3 +126,15 @@ func validateAbsolute(p string) error {
 	}
 	return fmt.Errorf("invalid mount path: '%s' mount path must be absolute", p)
 }
+
+// ValidateTmpfsMountDestination validates the destination of tmpfs mount.
+// Currently, we have only two obvious rule for validation:
+//  - path must not be "/"
+//  - path must be absolute
+// We should add more rules carefully (#30166)
+func ValidateTmpfsMountDestination(dest string) error {
+	if err := validateNotRoot(dest); err != nil {
+		return err
+	}
+	return validateAbsolute(dest)
+}