Browse Source

Have network files mounted read-only when -v parameter has 'ro' passed

Have network files mounted read-only when mounted using the -v
open and -v parameter has 'ro' passed.

Signed-off-by: Stefan Berger <stefanb@us.ibm.com>
Signed-off-by: Brian Goff <cpuguy83@gmail.com>
Stefan Berger 10 years ago
parent
commit
38295d4b48
3 changed files with 73 additions and 14 deletions
  1. 15 3
      daemon/container_unix.go
  2. 46 11
      integration-cli/docker_cli_run_test.go
  3. 12 0
      integration-cli/docker_utils.go

+ 15 - 3
daemon/container_unix.go

@@ -1128,28 +1128,40 @@ func (container *Container) networkMounts() []execdriver.Mount {
 	}
 	if container.ResolvConfPath != "" {
 		label.Relabel(container.ResolvConfPath, container.MountLabel, mode)
+		writable := !container.hostConfig.ReadonlyRootfs
+		if m, exists := container.MountPoints["/etc/resolv.conf"]; exists {
+			writable = m.RW
+		}
 		mounts = append(mounts, execdriver.Mount{
 			Source:      container.ResolvConfPath,
 			Destination: "/etc/resolv.conf",
-			Writable:    !container.hostConfig.ReadonlyRootfs,
+			Writable:    writable,
 			Private:     true,
 		})
 	}
 	if container.HostnamePath != "" {
 		label.Relabel(container.HostnamePath, container.MountLabel, mode)
+		writable := !container.hostConfig.ReadonlyRootfs
+		if m, exists := container.MountPoints["/etc/hostname"]; exists {
+			writable = m.RW
+		}
 		mounts = append(mounts, execdriver.Mount{
 			Source:      container.HostnamePath,
 			Destination: "/etc/hostname",
-			Writable:    !container.hostConfig.ReadonlyRootfs,
+			Writable:    writable,
 			Private:     true,
 		})
 	}
 	if container.HostsPath != "" {
 		label.Relabel(container.HostsPath, container.MountLabel, mode)
+		writable := !container.hostConfig.ReadonlyRootfs
+		if m, exists := container.MountPoints["/etc/hosts"]; exists {
+			writable = m.RW
+		}
 		mounts = append(mounts, execdriver.Mount{
 			Source:      container.HostsPath,
 			Destination: "/etc/hosts",
-			Writable:    !container.hostConfig.ReadonlyRootfs,
+			Writable:    writable,
 			Private:     true,
 		})
 	}

+ 46 - 11
integration-cli/docker_cli_run_test.go

@@ -2561,23 +2561,58 @@ func (s *DockerSuite) TestRunWriteFilteredProc(c *check.C) {
 
 func (s *DockerSuite) TestRunNetworkFilesBindMount(c *check.C) {
 	testRequires(c, SameHostDaemon)
-	name := "test-nwfiles-mount"
 
-	f, err := ioutil.TempFile("", name)
-	c.Assert(err, check.IsNil)
+	expected := "test123"
 
-	filename := f.Name()
+	filename := createTmpFile(c, expected)
 	defer os.Remove(filename)
 
-	expected := "test123"
+	nwfiles := []string{"/etc/resolv.conf", "/etc/hosts", "/etc/hostname"}
 
-	err = ioutil.WriteFile(filename, []byte(expected), 0644)
-	c.Assert(err, check.IsNil)
+	for i := range nwfiles {
+		actual, _ := dockerCmd(c, "run", "-v", filename+":"+nwfiles[i], "busybox", "cat", nwfiles[i])
+		if actual != expected {
+			c.Fatalf("expected %s be: %q, but was: %q", nwfiles[i], expected, actual)
+		}
+	}
+}
 
-	var actual string
-	actual, _ = dockerCmd(c, "run", "-v", filename+":/etc/resolv.conf", "busybox", "cat", "/etc/resolv.conf")
-	if actual != expected {
-		c.Fatalf("expected resolv.conf be: %q, but was: %q", expected, actual)
+func (s *DockerSuite) TestRunNetworkFilesBindMountRO(c *check.C) {
+	testRequires(c, SameHostDaemon)
+
+	filename := createTmpFile(c, "test123")
+	defer os.Remove(filename)
+
+	nwfiles := []string{"/etc/resolv.conf", "/etc/hosts", "/etc/hostname"}
+
+	for i := range nwfiles {
+		_, exitCode, err := dockerCmdWithError("run", "-v", filename+":"+nwfiles[i]+":ro", "busybox", "touch", nwfiles[i])
+		if err == nil || exitCode == 0 {
+			c.Fatalf("run should fail because bind mount of %s is ro: exit code %d", nwfiles[i], exitCode)
+		}
+	}
+}
+
+func (s *DockerSuite) TestRunNetworkFilesBindMountROFilesystem(c *check.C) {
+	testRequires(c, SameHostDaemon)
+
+	filename := createTmpFile(c, "test123")
+	defer os.Remove(filename)
+
+	nwfiles := []string{"/etc/resolv.conf", "/etc/hosts", "/etc/hostname"}
+
+	for i := range nwfiles {
+		_, exitCode := dockerCmd(c, "run", "-v", filename+":"+nwfiles[i], "--read-only", "busybox", "touch", nwfiles[i])
+		if exitCode != 0 {
+			c.Fatalf("run should not fail because %s is mounted writable on read-only root filesystem: exit code %d", nwfiles[i], exitCode)
+		}
+	}
+
+	for i := range nwfiles {
+		_, exitCode, err := dockerCmdWithError("run", "-v", filename+":"+nwfiles[i]+":ro", "--read-only", "busybox", "touch", nwfiles[i])
+		if err == nil || exitCode == 0 {
+			c.Fatalf("run should fail because %s is mounted read-only on read-only root filesystem: exit code %d", nwfiles[i], exitCode)
+		}
 	}
 }
 

+ 12 - 0
integration-cli/docker_utils.go

@@ -1326,3 +1326,15 @@ func appendBaseEnv(env []string) []string {
 	}
 	return env
 }
+
+func createTmpFile(c *check.C, content string) string {
+	f, err := ioutil.TempFile("", "testfile")
+	c.Assert(err, check.IsNil)
+
+	filename := f.Name()
+
+	err = ioutil.WriteFile(filename, []byte(content), 0644)
+	c.Assert(err, check.IsNil)
+
+	return filename
+}