Browse code

Ensure WORKDIR is created with remapped root ownership

Correct creation of a non-existing WORKDIR during docker build to use
remapped root uid/gid on mkdir

Docker-DCO-1.1-Signed-off-by: Phil Estes <estesp@linux.vnet.ibm.com> (github: estesp)

Phil Estes authored on 2016/03/09 00:40:30
Showing 5 changed files
... ...
@@ -18,10 +18,10 @@ import (
18 18
 	"github.com/docker/docker/daemon/network"
19 19
 	"github.com/docker/docker/image"
20 20
 	"github.com/docker/docker/layer"
21
+	"github.com/docker/docker/pkg/idtools"
21 22
 	"github.com/docker/docker/pkg/promise"
22 23
 	"github.com/docker/docker/pkg/signal"
23 24
 	"github.com/docker/docker/pkg/symlink"
24
-	"github.com/docker/docker/pkg/system"
25 25
 	"github.com/docker/docker/runconfig"
26 26
 	"github.com/docker/docker/volume"
27 27
 	containertypes "github.com/docker/engine-api/types/container"
... ...
@@ -184,7 +184,7 @@ func (container *Container) WriteHostConfig() error {
184 184
 }
185 185
 
186 186
 // SetupWorkingDirectory sets up the container's working directory as set in container.Config.WorkingDir
187
-func (container *Container) SetupWorkingDirectory() error {
187
+func (container *Container) SetupWorkingDirectory(rootUID, rootGID int) error {
188 188
 	if container.Config.WorkingDir == "" {
189 189
 		return nil
190 190
 	}
... ...
@@ -202,7 +202,7 @@ func (container *Container) SetupWorkingDirectory() error {
202 202
 		return err
203 203
 	}
204 204
 
205
-	if err := system.MkdirAll(pth, 0755); err != nil {
205
+	if err := idtools.MkdirAllNewAs(pth, 0755, rootUID, rootGID); err != nil {
206 206
 		pthInfo, err2 := os.Stat(pth)
207 207
 		if err2 == nil && pthInfo != nil && !pthInfo.IsDir() {
208 208
 			return fmt.Errorf("Cannot mkdir: %s is not a directory", container.Config.WorkingDir)
... ...
@@ -21,7 +21,8 @@ func (daemon *Daemon) createContainerPlatformSpecificSettings(container *contain
21 21
 	}
22 22
 	defer daemon.Unmount(container)
23 23
 
24
-	if err := container.SetupWorkingDirectory(); err != nil {
24
+	rootUID, rootGID := daemon.GetRemappedUIDGID()
25
+	if err := container.SetupWorkingDirectory(rootUID, rootGID); err != nil {
25 26
 		return err
26 27
 	}
27 28
 
... ...
@@ -126,7 +126,8 @@ func (daemon *Daemon) containerStart(container *container.Container) (err error)
126 126
 	if err != nil {
127 127
 		return err
128 128
 	}
129
-	if err := container.SetupWorkingDirectory(); err != nil {
129
+	rootUID, rootGID := daemon.GetRemappedUIDGID()
130
+	if err := container.SetupWorkingDirectory(rootUID, rootGID); err != nil {
130 131
 		return err
131 132
 	}
132 133
 	env := container.CreateDaemonEnvironment(linkedEnv)
... ...
@@ -844,6 +844,17 @@ RUN ls -l /new_dir`,
844 844
 	}
845 845
 }
846 846
 
847
+func (s *DockerSuite) TestBuildWorkdirIsContainerRoot(c *check.C) {
848
+	testRequires(c, DaemonIsLinux) // Linux specific test
849
+	name := "testworkdirownership"
850
+	if _, err := buildImage(name, `FROM busybox
851
+WORKDIR /new_dir
852
+RUN ls -l /
853
+RUN [ $(ls -l / | grep new_dir | awk '{print $3":"$4}') = 'root:root' ]`, true); err != nil {
854
+		c.Fatal(err)
855
+	}
856
+}
857
+
847 858
 func (s *DockerSuite) TestBuildAddMultipleFilesToFile(c *check.C) {
848 859
 	name := "testaddmultiplefilestofile"
849 860
 
... ...
@@ -1742,7 +1742,7 @@ func (s *DockerSuite) TestRunCleanupCmdOnEntrypoint(c *check.C) {
1742 1742
 // TestRunWorkdirExistsAndIsFile checks that if 'docker run -w' with existing file can be detected
1743 1743
 func (s *DockerSuite) TestRunWorkdirExistsAndIsFile(c *check.C) {
1744 1744
 	existingFile := "/bin/cat"
1745
-	expected := "Cannot mkdir: /bin/cat is not a directory"
1745
+	expected := "not a directory"
1746 1746
 	if daemonPlatform == "windows" {
1747 1747
 		existingFile = `\windows\system32\ntdll.dll`
1748 1748
 		expected = `Cannot mkdir: \windows\system32\ntdll.dll is not a directory.`
... ...
@@ -1750,7 +1750,7 @@ func (s *DockerSuite) TestRunWorkdirExistsAndIsFile(c *check.C) {
1750 1750
 
1751 1751
 	out, exitCode, err := dockerCmdWithError("run", "-w", existingFile, "busybox")
1752 1752
 	if !(err != nil && exitCode == 125 && strings.Contains(out, expected)) {
1753
-		c.Fatalf("Docker must complains about making dir with exitCode 125 but we got out: %s, exitCode: %d", out, exitCode)
1753
+		c.Fatalf("Existing binary as a directory should error out with exitCode 125; we got: %s, exitCode: %d", out, exitCode)
1754 1754
 	}
1755 1755
 }
1756 1756