diff --git a/daemon/execdriver/driver_unix.go b/daemon/execdriver/driver_unix.go index 19550b3419..3ed3c8170f 100644 --- a/daemon/execdriver/driver_unix.go +++ b/daemon/execdriver/driver_unix.go @@ -140,7 +140,7 @@ func InitContainer(c *Command) *configs.Config { container.Hostname = getEnv("HOSTNAME", c.ProcessConfig.Env) container.Cgroups.Name = c.ID container.Cgroups.Resources.AllowedDevices = c.AllowedDevices - container.Devices = c.AutoCreatedDevices + container.Devices = filterDevices(c.AutoCreatedDevices, (c.RemappedRoot.UID != 0)) container.Rootfs = c.Rootfs container.Readonlyfs = c.ReadonlyRootfs // This can be overridden later by driver during mount setup based @@ -154,6 +154,24 @@ func InitContainer(c *Command) *configs.Config { return container } +func filterDevices(devices []*configs.Device, userNamespacesEnabled bool) []*configs.Device { + if !userNamespacesEnabled { + return devices + } + + filtered := []*configs.Device{} + // if we have user namespaces enabled, these devices will not be created + // because of the mknod limitation in the kernel for an unprivileged process. + // Rather, they will be bind-mounted, which will only work if they exist; + // check for existence and remove non-existent entries from the list + for _, device := range devices { + if _, err := os.Stat(device.Path); err == nil { + filtered = append(filtered, device) + } + } + return filtered +} + func getEnv(key string, env []string) string { for _, pair := range env { parts := strings.SplitN(pair, "=", 2)