diff --git a/daemon/daemon_unix.go b/daemon/daemon_unix.go index 3050a381ba..02e2ca9f80 100644 --- a/daemon/daemon_unix.go +++ b/daemon/daemon_unix.go @@ -585,12 +585,12 @@ func setupInitLayer(initLayer string, rootUID, rootGID int) error { if _, err := os.Stat(filepath.Join(initLayer, pth)); err != nil { if os.IsNotExist(err) { - if err := idtools.MkdirAllAs(filepath.Join(initLayer, filepath.Dir(pth)), 0755, rootUID, rootGID); err != nil { + if err := idtools.MkdirAllNewAs(filepath.Join(initLayer, filepath.Dir(pth)), 0755, rootUID, rootGID); err != nil { return err } switch typ { case "dir": - if err := idtools.MkdirAllAs(filepath.Join(initLayer, pth), 0755, rootUID, rootGID); err != nil { + if err := idtools.MkdirAllNewAs(filepath.Join(initLayer, pth), 0755, rootUID, rootGID); err != nil { return err } case "file": @@ -598,8 +598,8 @@ func setupInitLayer(initLayer string, rootUID, rootGID int) error { if err != nil { return err } - f.Close() f.Chown(rootUID, rootGID) + f.Close() default: if err := os.Symlink(typ, filepath.Join(initLayer, pth)); err != nil { return err diff --git a/integration-cli/docker_cli_run_test.go b/integration-cli/docker_cli_run_test.go index 1e847d805e..c20b1cc1aa 100644 --- a/integration-cli/docker_cli_run_test.go +++ b/integration-cli/docker_cli_run_test.go @@ -3762,6 +3762,29 @@ func (s *DockerSuite) TestRunInvalidReference(c *check.C) { } } +// Test fix for issue #17854 +func (s *DockerSuite) TestRunInitLayerPathOwnership(c *check.C) { + // Not applicable on Windows as it does not support Linux uid/gid ownership + testRequires(c, DaemonIsLinux) + name := "testetcfileownership" + _, err := buildImage(name, + `FROM busybox + RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd + RUN echo 'dockerio:x:1001:' >> /etc/group + RUN chown dockerio:dockerio /etc`, + true) + if err != nil { + c.Fatal(err) + } + + // Test that dockerio ownership of /etc is retained at runtime + out, _ := dockerCmd(c, "run", "--rm", name, "stat", "-c", "%U:%G", "/etc") + out = strings.TrimSpace(out) + if out != "dockerio:dockerio" { + c.Fatalf("Wrong /etc ownership: expected dockerio:dockerio, got %q", out) + } +} + func (s *DockerSuite) TestRunWithOomScoreAdj(c *check.C) { testRequires(c, DaemonIsLinux)