Pārlūkot izejas kodu

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 <david.r.jenni@gmail.com>
David R. Jenni 10 gadi atpakaļ
vecāks
revīzija
c913c9921b
2 mainītis faili ar 34 papildinājumiem un 2 dzēšanām
  1. 22 2
      daemon/container_linux.go
  2. 12 0
      integration-cli/docker_cli_run_test.go

+ 22 - 2
daemon/container_linux.go

@@ -227,9 +227,10 @@ func populateCommand(c *Container, env []string) error {
 
 
 		userSpecifiedDevices = append(userSpecifiedDevices, devs...)
 		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
 	// TODO: this can be removed after lxc-conf is fully deprecated
 	lxcConfig, err := mergeLxcConfIntoOptions(c.hostConfig)
 	lxcConfig, err := mergeLxcConfIntoOptions(c.hostConfig)
@@ -309,6 +310,25 @@ func populateCommand(c *Container, env []string) error {
 	return nil
 	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
 // GetSize, return real size, virtual size
 func (container *Container) GetSize() (int64, int64) {
 func (container *Container) GetSize() (int64, int64) {
 	var (
 	var (

+ 12 - 0
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)
 		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)
+	}
+}