Browse code

Merge pull request #14965 from stefanberger/nohidevols2

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

David Calavera authored on 2015/08/08 11:10:59
Showing 3 changed files
... ...
@@ -1128,28 +1128,40 @@ func (container *Container) networkMounts() []execdriver.Mount {
1128 1128
 	}
1129 1129
 	if container.ResolvConfPath != "" {
1130 1130
 		label.Relabel(container.ResolvConfPath, container.MountLabel, mode)
1131
+		writable := !container.hostConfig.ReadonlyRootfs
1132
+		if m, exists := container.MountPoints["/etc/resolv.conf"]; exists {
1133
+			writable = m.RW
1134
+		}
1131 1135
 		mounts = append(mounts, execdriver.Mount{
1132 1136
 			Source:      container.ResolvConfPath,
1133 1137
 			Destination: "/etc/resolv.conf",
1134
-			Writable:    !container.hostConfig.ReadonlyRootfs,
1138
+			Writable:    writable,
1135 1139
 			Private:     true,
1136 1140
 		})
1137 1141
 	}
1138 1142
 	if container.HostnamePath != "" {
1139 1143
 		label.Relabel(container.HostnamePath, container.MountLabel, mode)
1144
+		writable := !container.hostConfig.ReadonlyRootfs
1145
+		if m, exists := container.MountPoints["/etc/hostname"]; exists {
1146
+			writable = m.RW
1147
+		}
1140 1148
 		mounts = append(mounts, execdriver.Mount{
1141 1149
 			Source:      container.HostnamePath,
1142 1150
 			Destination: "/etc/hostname",
1143
-			Writable:    !container.hostConfig.ReadonlyRootfs,
1151
+			Writable:    writable,
1144 1152
 			Private:     true,
1145 1153
 		})
1146 1154
 	}
1147 1155
 	if container.HostsPath != "" {
1148 1156
 		label.Relabel(container.HostsPath, container.MountLabel, mode)
1157
+		writable := !container.hostConfig.ReadonlyRootfs
1158
+		if m, exists := container.MountPoints["/etc/hosts"]; exists {
1159
+			writable = m.RW
1160
+		}
1149 1161
 		mounts = append(mounts, execdriver.Mount{
1150 1162
 			Source:      container.HostsPath,
1151 1163
 			Destination: "/etc/hosts",
1152
-			Writable:    !container.hostConfig.ReadonlyRootfs,
1164
+			Writable:    writable,
1153 1165
 			Private:     true,
1154 1166
 		})
1155 1167
 	}
... ...
@@ -2561,23 +2561,58 @@ func (s *DockerSuite) TestRunWriteFilteredProc(c *check.C) {
2561 2561
 
2562 2562
 func (s *DockerSuite) TestRunNetworkFilesBindMount(c *check.C) {
2563 2563
 	testRequires(c, SameHostDaemon)
2564
-	name := "test-nwfiles-mount"
2565 2564
 
2566
-	f, err := ioutil.TempFile("", name)
2567
-	c.Assert(err, check.IsNil)
2565
+	expected := "test123"
2568 2566
 
2569
-	filename := f.Name()
2567
+	filename := createTmpFile(c, expected)
2570 2568
 	defer os.Remove(filename)
2571 2569
 
2572
-	expected := "test123"
2570
+	nwfiles := []string{"/etc/resolv.conf", "/etc/hosts", "/etc/hostname"}
2573 2571
 
2574
-	err = ioutil.WriteFile(filename, []byte(expected), 0644)
2575
-	c.Assert(err, check.IsNil)
2572
+	for i := range nwfiles {
2573
+		actual, _ := dockerCmd(c, "run", "-v", filename+":"+nwfiles[i], "busybox", "cat", nwfiles[i])
2574
+		if actual != expected {
2575
+			c.Fatalf("expected %s be: %q, but was: %q", nwfiles[i], expected, actual)
2576
+		}
2577
+	}
2578
+}
2576 2579
 
2577
-	var actual string
2578
-	actual, _ = dockerCmd(c, "run", "-v", filename+":/etc/resolv.conf", "busybox", "cat", "/etc/resolv.conf")
2579
-	if actual != expected {
2580
-		c.Fatalf("expected resolv.conf be: %q, but was: %q", expected, actual)
2580
+func (s *DockerSuite) TestRunNetworkFilesBindMountRO(c *check.C) {
2581
+	testRequires(c, SameHostDaemon)
2582
+
2583
+	filename := createTmpFile(c, "test123")
2584
+	defer os.Remove(filename)
2585
+
2586
+	nwfiles := []string{"/etc/resolv.conf", "/etc/hosts", "/etc/hostname"}
2587
+
2588
+	for i := range nwfiles {
2589
+		_, exitCode, err := dockerCmdWithError("run", "-v", filename+":"+nwfiles[i]+":ro", "busybox", "touch", nwfiles[i])
2590
+		if err == nil || exitCode == 0 {
2591
+			c.Fatalf("run should fail because bind mount of %s is ro: exit code %d", nwfiles[i], exitCode)
2592
+		}
2593
+	}
2594
+}
2595
+
2596
+func (s *DockerSuite) TestRunNetworkFilesBindMountROFilesystem(c *check.C) {
2597
+	testRequires(c, SameHostDaemon)
2598
+
2599
+	filename := createTmpFile(c, "test123")
2600
+	defer os.Remove(filename)
2601
+
2602
+	nwfiles := []string{"/etc/resolv.conf", "/etc/hosts", "/etc/hostname"}
2603
+
2604
+	for i := range nwfiles {
2605
+		_, exitCode := dockerCmd(c, "run", "-v", filename+":"+nwfiles[i], "--read-only", "busybox", "touch", nwfiles[i])
2606
+		if exitCode != 0 {
2607
+			c.Fatalf("run should not fail because %s is mounted writable on read-only root filesystem: exit code %d", nwfiles[i], exitCode)
2608
+		}
2609
+	}
2610
+
2611
+	for i := range nwfiles {
2612
+		_, exitCode, err := dockerCmdWithError("run", "-v", filename+":"+nwfiles[i]+":ro", "--read-only", "busybox", "touch", nwfiles[i])
2613
+		if err == nil || exitCode == 0 {
2614
+			c.Fatalf("run should fail because %s is mounted read-only on read-only root filesystem: exit code %d", nwfiles[i], exitCode)
2615
+		}
2581 2616
 	}
2582 2617
 }
2583 2618
 
... ...
@@ -1341,3 +1341,15 @@ func appendBaseEnv(env []string) []string {
1341 1341
 	}
1342 1342
 	return env
1343 1343
 }
1344
+
1345
+func createTmpFile(c *check.C, content string) string {
1346
+	f, err := ioutil.TempFile("", "testfile")
1347
+	c.Assert(err, check.IsNil)
1348
+
1349
+	filename := f.Name()
1350
+
1351
+	err = ioutil.WriteFile(filename, []byte(content), 0644)
1352
+	c.Assert(err, check.IsNil)
1353
+
1354
+	return filename
1355
+}