From 142454692f282909a9f8a441fb249a24fbecdde3 Mon Sep 17 00:00:00 2001 From: Akihiro Suda Date: Mon, 16 Jan 2017 09:52:43 +0000 Subject: [PATCH] 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 Upstream-commit: 4a8799dc0a000a74eae49a01b054ae687bc18f73 Component: engine --- components/engine/daemon/daemon_unix.go | 7 +++ .../docker_cli_create_unix_test.go | 43 +++++++++++++++++++ components/engine/volume/validate.go | 15 +++++++ 3 files changed, 65 insertions(+) create mode 100644 components/engine/integration-cli/docker_cli_create_unix_test.go diff --git a/components/engine/daemon/daemon_unix.go b/components/engine/daemon/daemon_unix.go index ac27e35c02..cdfba040a1 100644 --- a/components/engine/daemon/daemon_unix.go +++ b/components/engine/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 } diff --git a/components/engine/integration-cli/docker_cli_create_unix_test.go b/components/engine/integration-cli/docker_cli_create_unix_test.go new file mode 100644 index 0000000000..1b0bb4a3dc --- /dev/null +++ b/components/engine/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) + } + } +} diff --git a/components/engine/volume/validate.go b/components/engine/volume/validate.go index 27a8c5d5b0..42396a0dad 100644 --- a/components/engine/volume/validate.go +++ b/components/engine/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) +}