From c913c9921b7caa11e8500d2ebb4fa97303c876be Mon Sep 17 00:00:00 2001 From: "David R. Jenni" Date: Fri, 29 May 2015 17:29:56 +0200 Subject: [PATCH] Fix issue #10184. Merge user specified devices correctly with default devices. Otherwise the user specified devices end up without permissions. Signed-off-by: David R. Jenni --- daemon/container_linux.go | 24 ++++++++++++++++++++++-- integration-cli/docker_cli_run_test.go | 12 ++++++++++++ 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/daemon/container_linux.go b/daemon/container_linux.go index 9ee94da9f2..5f710ae9ad 100644 --- a/daemon/container_linux.go +++ b/daemon/container_linux.go @@ -227,9 +227,10 @@ func populateCommand(c *Container, env []string) error { userSpecifiedDevices = append(userSpecifiedDevices, devs...) } - allowedDevices := append(configs.DefaultAllowedDevices, userSpecifiedDevices...) - autoCreatedDevices := append(configs.DefaultAutoCreatedDevices, userSpecifiedDevices...) + allowedDevices := mergeDevices(configs.DefaultAllowedDevices, userSpecifiedDevices) + + autoCreatedDevices := mergeDevices(configs.DefaultAutoCreatedDevices, userSpecifiedDevices) // TODO: this can be removed after lxc-conf is fully deprecated lxcConfig, err := mergeLxcConfIntoOptions(c.hostConfig) @@ -309,6 +310,25 @@ func populateCommand(c *Container, env []string) error { return nil } +func mergeDevices(defaultDevices, userDevices []*configs.Device) []*configs.Device { + if len(userDevices) == 0 { + return defaultDevices + } + + paths := map[string]*configs.Device{} + for _, d := range userDevices { + paths[d.Path] = d + } + + var devs []*configs.Device + for _, d := range defaultDevices { + if _, defined := paths[d.Path]; !defined { + devs = append(devs, d) + } + } + return append(devs, userDevices...) +} + // GetSize, return real size, virtual size func (container *Container) GetSize() (int64, int64) { var ( diff --git a/integration-cli/docker_cli_run_test.go b/integration-cli/docker_cli_run_test.go index 866a579bb4..1d1cdb27de 100644 --- a/integration-cli/docker_cli_run_test.go +++ b/integration-cli/docker_cli_run_test.go @@ -3156,3 +3156,15 @@ func (s *DockerSuite) TestRunPublishPort(c *check.C) { c.Fatalf("run without --publish-all should not publish port, out should be nil, but got: %s", out) } } + +// Issue #10184. +func (s *DockerSuite) TestDevicePermissions(c *check.C) { + const permissions = "crw-rw-rw-" + out, status := dockerCmd(c, "run", "--device", "/dev/fuse:/dev/fuse:mrw", "busybox:latest", "ls", "-l", "/dev/fuse") + if status != 0 { + c.Fatalf("expected status 0, got %d", status) + } + if !strings.HasPrefix(out, permissions) { + c.Fatalf("output should begin with %q, got %q", permissions, out) + } +}