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>
| ... | ... |
@@ -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 |
+} |