Browse code

Fix network connectivity problem for non-root users

If a container was started with a non-root user the container
may not be able to resolve DNS names because of too restrictive
permission in the /etc/resolv.conf container file. This problem
is in how this file gets created in libnetwork and ths PR
attempts to fix the issue by vendoring in the libnetwork code
with the fix.

Signed-off-by: Jana Radhakrishnan <mrjana@docker.com>

Jana Radhakrishnan authored on 2015/05/20 15:06:44
Showing 4 changed files
... ...
@@ -55,7 +55,7 @@ clone hg code.google.com/p/go.net 84a4013f96e0
55 55
 clone hg code.google.com/p/gosqlite 74691fb6f837
56 56
 
57 57
 #get libnetwork packages
58
-clone git github.com/docker/libnetwork v0.2
58
+clone git github.com/docker/libnetwork b39597744b0978fe4aeb9f3a099ba42f7b6c4a1f
59 59
 clone git github.com/vishvananda/netns 008d17ae001344769b031375bdb38a86219154c6
60 60
 clone git github.com/vishvananda/netlink 8eb64238879fed52fd51c5b30ad20b928fb4c36c
61 61
 
... ...
@@ -1455,6 +1455,32 @@ func (s *DockerSuite) TestRunDnsOptionsBasedOnHostResolvConf(c *check.C) {
1455 1455
 	}
1456 1456
 }
1457 1457
 
1458
+// Test to see if a non-root user can resolve a DNS name and reach out to it. Also
1459
+// check if the container resolv.conf file has atleast 0644 perm.
1460
+func (s *DockerSuite) TestRunNonRootUserResolvName(c *check.C) {
1461
+	testRequires(c, SameHostDaemon)
1462
+
1463
+	cmd := exec.Command(dockerBinary, "run", "--name=testperm", "--user=default", "busybox", "ping", "-c", "1", "www.docker.io")
1464
+	if out, err := runCommand(cmd); err != nil {
1465
+		c.Fatal(err, out)
1466
+	}
1467
+
1468
+	cID, err := getIDByName("testperm")
1469
+	if err != nil {
1470
+		c.Fatal(err)
1471
+	}
1472
+
1473
+	fmode := (os.FileMode)(0644)
1474
+	finfo, err := os.Stat(containerStorageFile(cID, "resolv.conf"))
1475
+	if err != nil {
1476
+		c.Fatal(err)
1477
+	}
1478
+
1479
+	if (finfo.Mode() & fmode) != fmode {
1480
+		c.Fatalf("Expected container resolv.conf mode to be atleast %s, instead got %s", fmode.String(), finfo.Mode().String())
1481
+	}
1482
+}
1483
+
1458 1484
 // Test if container resolv.conf gets updated the next time it restarts
1459 1485
 // if host /etc/resolv.conf has changed. This only applies if the container
1460 1486
 // uses the host's /etc/resolv.conf and does not have any dns options provided.
... ...
@@ -548,6 +548,11 @@ func (ep *endpoint) updateDNS(resolvConf []byte) error {
548 548
 		return err
549 549
 	}
550 550
 
551
+	// Change the perms to 0644 since ioutil.TempFile creates it by default as 0600
552
+	if err := os.Chmod(tmpResolvFile.Name(), 0644); err != nil {
553
+		return err
554
+	}
555
+
551 556
 	// write the updates to the temp files
552 557
 	if err = ioutil.WriteFile(tmpHashFile.Name(), []byte(newHash), 0644); err != nil {
553 558
 		return err
... ...
@@ -1137,6 +1137,16 @@ func TestResolvConf(t *testing.T) {
1137 1137
 		}
1138 1138
 	}()
1139 1139
 
1140
+	finfo, err := os.Stat(resolvConfPath)
1141
+	if err != nil {
1142
+		t.Fatal(err)
1143
+	}
1144
+
1145
+	fmode := (os.FileMode)(0644)
1146
+	if finfo.Mode() != fmode {
1147
+		t.Fatalf("Expected file mode %s, got %s", fmode.String(), finfo.Mode().String())
1148
+	}
1149
+
1140 1150
 	content, err := ioutil.ReadFile(resolvConfPath)
1141 1151
 	if err != nil {
1142 1152
 		t.Fatal(err)