Browse code

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 authored on 2017/01/16 18:52:43
Showing 3 changed files
... ...
@@ -29,6 +29,7 @@ import (
29 29
 	"github.com/docker/docker/pkg/parsers/kernel"
30 30
 	"github.com/docker/docker/pkg/sysinfo"
31 31
 	"github.com/docker/docker/runconfig"
32
+	"github.com/docker/docker/volume"
32 33
 	"github.com/docker/libnetwork"
33 34
 	nwconfig "github.com/docker/libnetwork/config"
34 35
 	"github.com/docker/libnetwork/drivers/bridge"
... ...
@@ -553,6 +554,12 @@ func verifyPlatformContainerSettings(daemon *Daemon, hostConfig *containertypes.
553 553
 		return warnings, fmt.Errorf("Unknown runtime specified %s", hostConfig.Runtime)
554 554
 	}
555 555
 
556
+	for dest := range hostConfig.Tmpfs {
557
+		if err := volume.ValidateTmpfsMountDestination(dest); err != nil {
558
+			return warnings, err
559
+		}
560
+	}
561
+
556 562
 	return warnings, nil
557 563
 }
558 564
 
559 565
new file mode 100644
... ...
@@ -0,0 +1,43 @@
0
+// +build !windows
1
+
2
+package main
3
+
4
+import (
5
+	"strings"
6
+
7
+	"github.com/go-check/check"
8
+)
9
+
10
+// Test case for #30166 (target was not validated)
11
+func (s *DockerSuite) TestCreateTmpfsMountsTarget(c *check.C) {
12
+	testRequires(c, DaemonIsLinux)
13
+	type testCase struct {
14
+		target        string
15
+		expectedError string
16
+	}
17
+	cases := []testCase{
18
+		{
19
+			target:        ".",
20
+			expectedError: "mount path must be absolute",
21
+		},
22
+		{
23
+			target:        "foo",
24
+			expectedError: "mount path must be absolute",
25
+		},
26
+		{
27
+			target:        "/",
28
+			expectedError: "destination can't be '/'",
29
+		},
30
+		{
31
+			target:        "//",
32
+			expectedError: "destination can't be '/'",
33
+		},
34
+	}
35
+	for _, x := range cases {
36
+		out, _, _ := dockerCmdWithError("create", "--tmpfs", x.target, "busybox", "sh")
37
+		if x.expectedError != "" && !strings.Contains(out, x.expectedError) {
38
+			c.Fatalf("mounting tmpfs over %q should fail with %q, but got %q",
39
+				x.target, x.expectedError, out)
40
+		}
41
+	}
42
+}
... ...
@@ -91,6 +91,9 @@ func validateMountConfig(mnt *mount.Mount, options ...func(*validateOpts)) error
91 91
 		if len(mnt.Source) != 0 {
92 92
 			return &errMountConfig{mnt, errExtraField("Source")}
93 93
 		}
94
+		if err := ValidateTmpfsMountDestination(mnt.Target); err != nil {
95
+			return &errMountConfig{mnt, err}
96
+		}
94 97
 		if _, err := ConvertTmpfsOptions(mnt.TmpfsOptions, mnt.ReadOnly); err != nil {
95 98
 			return &errMountConfig{mnt, err}
96 99
 		}
... ...
@@ -123,3 +126,15 @@ func validateAbsolute(p string) error {
123 123
 	}
124 124
 	return fmt.Errorf("invalid mount path: '%s' mount path must be absolute", p)
125 125
 }
126
+
127
+// ValidateTmpfsMountDestination validates the destination of tmpfs mount.
128
+// Currently, we have only two obvious rule for validation:
129
+//  - path must not be "/"
130
+//  - path must be absolute
131
+// We should add more rules carefully (#30166)
132
+func ValidateTmpfsMountDestination(dest string) error {
133
+	if err := validateNotRoot(dest); err != nil {
134
+		return err
135
+	}
136
+	return validateAbsolute(dest)
137
+}