Browse code

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 authored on 2015/05/30 00:29:56
Showing 2 changed files
... ...
@@ -227,9 +227,10 @@ func populateCommand(c *Container, env []string) error {
227 227
 
228 228
 		userSpecifiedDevices = append(userSpecifiedDevices, devs...)
229 229
 	}
230
-	allowedDevices := append(configs.DefaultAllowedDevices, userSpecifiedDevices...)
231 230
 
232
-	autoCreatedDevices := append(configs.DefaultAutoCreatedDevices, userSpecifiedDevices...)
231
+	allowedDevices := mergeDevices(configs.DefaultAllowedDevices, userSpecifiedDevices)
232
+
233
+	autoCreatedDevices := mergeDevices(configs.DefaultAutoCreatedDevices, userSpecifiedDevices)
233 234
 
234 235
 	// TODO: this can be removed after lxc-conf is fully deprecated
235 236
 	lxcConfig, err := mergeLxcConfIntoOptions(c.hostConfig)
... ...
@@ -309,6 +310,25 @@ func populateCommand(c *Container, env []string) error {
309 309
 	return nil
310 310
 }
311 311
 
312
+func mergeDevices(defaultDevices, userDevices []*configs.Device) []*configs.Device {
313
+	if len(userDevices) == 0 {
314
+		return defaultDevices
315
+	}
316
+
317
+	paths := map[string]*configs.Device{}
318
+	for _, d := range userDevices {
319
+		paths[d.Path] = d
320
+	}
321
+
322
+	var devs []*configs.Device
323
+	for _, d := range defaultDevices {
324
+		if _, defined := paths[d.Path]; !defined {
325
+			devs = append(devs, d)
326
+		}
327
+	}
328
+	return append(devs, userDevices...)
329
+}
330
+
312 331
 // GetSize, return real size, virtual size
313 332
 func (container *Container) GetSize() (int64, int64) {
314 333
 	var (
... ...
@@ -3156,3 +3156,15 @@ func (s *DockerSuite) TestRunPublishPort(c *check.C) {
3156 3156
 		c.Fatalf("run without --publish-all should not publish port, out should be nil, but got: %s", out)
3157 3157
 	}
3158 3158
 }
3159
+
3160
+// Issue #10184.
3161
+func (s *DockerSuite) TestDevicePermissions(c *check.C) {
3162
+	const permissions = "crw-rw-rw-"
3163
+	out, status := dockerCmd(c, "run", "--device", "/dev/fuse:/dev/fuse:mrw", "busybox:latest", "ls", "-l", "/dev/fuse")
3164
+	if status != 0 {
3165
+		c.Fatalf("expected status 0, got %d", status)
3166
+	}
3167
+	if !strings.HasPrefix(out, permissions) {
3168
+		c.Fatalf("output should begin with %q, got %q", permissions, out)
3169
+	}
3170
+}