Merge pull request #21487 from tonistiigi/fix-old-dind

Fix setting cgroup permission to user/privileged devices
This commit is contained in:
Sebastiaan van Stijn 2016-03-24 22:56:39 -07:00
commit f3d824771a
4 changed files with 59 additions and 11 deletions

View File

@ -295,7 +295,18 @@ func specDevice(d *configs.Device) specs.Device {
}
}
func getDevicesFromPath(deviceMapping containertypes.DeviceMapping) (devs []specs.Device, err error) {
func specDeviceCgroup(d *configs.Device) specs.DeviceCgroup {
t := string(d.Type)
return specs.DeviceCgroup{
Allow: true,
Type: &t,
Major: &d.Major,
Minor: &d.Minor,
Access: &d.Permissions,
}
}
func getDevicesFromPath(deviceMapping containertypes.DeviceMapping) (devs []specs.Device, devPermissions []specs.DeviceCgroup, err error) {
resolvedPathOnHost := deviceMapping.PathOnHost
// check if it is a symbolic link
@ -309,7 +320,7 @@ func getDevicesFromPath(deviceMapping containertypes.DeviceMapping) (devs []spec
// if there was no error, return the device
if err == nil {
device.Path = deviceMapping.PathInContainer
return append(devs, specDevice(device)), nil
return append(devs, specDevice(device)), append(devPermissions, specDeviceCgroup(device)), nil
}
// if the device is not a device node
@ -330,6 +341,7 @@ func getDevicesFromPath(deviceMapping containertypes.DeviceMapping) (devs []spec
// add the device to userSpecified devices
childDevice.Path = strings.Replace(dpath, resolvedPathOnHost, deviceMapping.PathInContainer, 1)
devs = append(devs, specDevice(childDevice))
devPermissions = append(devPermissions, specDeviceCgroup(childDevice))
return nil
})
@ -337,10 +349,10 @@ func getDevicesFromPath(deviceMapping containertypes.DeviceMapping) (devs []spec
}
if len(devs) > 0 {
return devs, nil
return devs, devPermissions, nil
}
return devs, fmt.Errorf("error gathering device information while adding custom device %q: %s", deviceMapping.PathOnHost, err)
return devs, devPermissions, fmt.Errorf("error gathering device information while adding custom device %q: %s", deviceMapping.PathOnHost, err)
}
func mergeDevices(defaultDevices, userDevices []*configs.Device) []*configs.Device {

View File

@ -130,7 +130,7 @@ func getBlkioWeightDevices(config containertypes.Resources) ([]specs.WeightDevic
weight := weightDevice.Weight
d := specs.WeightDevice{Weight: &weight}
d.Major = int64(stat.Rdev / 256)
d.Major = int64(stat.Rdev % 256)
d.Minor = int64(stat.Rdev % 256)
blkioWeightDevices = append(blkioWeightDevices, d)
}
@ -187,7 +187,7 @@ func getBlkioReadIOpsDevices(config containertypes.Resources) ([]specs.ThrottleD
rate := iopsDevice.Rate
d := specs.ThrottleDevice{Rate: &rate}
d.Major = int64(stat.Rdev / 256)
d.Major = int64(stat.Rdev % 256)
d.Minor = int64(stat.Rdev % 256)
blkioReadIOpsDevice = append(blkioReadIOpsDevice, d)
}
@ -205,7 +205,7 @@ func getBlkioWriteIOpsDevices(config containertypes.Resources) ([]specs.Throttle
rate := iopsDevice.Rate
d := specs.ThrottleDevice{Rate: &rate}
d.Major = int64(stat.Rdev / 256)
d.Major = int64(stat.Rdev % 256)
d.Minor = int64(stat.Rdev % 256)
blkioWriteIOpsDevice = append(blkioWriteIOpsDevice, d)
}
@ -223,7 +223,7 @@ func getBlkioReadBpsDevices(config containertypes.Resources) ([]specs.ThrottleDe
rate := bpsDevice.Rate
d := specs.ThrottleDevice{Rate: &rate}
d.Major = int64(stat.Rdev / 256)
d.Major = int64(stat.Rdev % 256)
d.Minor = int64(stat.Rdev % 256)
blkioReadBpsDevice = append(blkioReadBpsDevice, d)
}
@ -241,7 +241,7 @@ func getBlkioWriteBpsDevices(config containertypes.Resources) ([]specs.ThrottleD
rate := bpsDevice.Rate
d := specs.ThrottleDevice{Rate: &rate}
d.Major = int64(stat.Rdev / 256)
d.Major = int64(stat.Rdev % 256)
d.Minor = int64(stat.Rdev % 256)
blkioWriteBpsDevice = append(blkioWriteBpsDevice, d)
}

View File

@ -78,6 +78,7 @@ func setResources(s *specs.Spec, r containertypes.Resources) error {
func setDevices(s *specs.Spec, c *container.Container) error {
// Build lists of devices allowed and created within the container.
var devs []specs.Device
devPermissions := s.Linux.Resources.Devices
if c.HostConfig.Privileged {
hostDevices, err := devices.HostDevices()
if err != nil {
@ -86,18 +87,26 @@ func setDevices(s *specs.Spec, c *container.Container) error {
for _, d := range hostDevices {
devs = append(devs, specDevice(d))
}
rwm := "rwm"
devPermissions = []specs.DeviceCgroup{
{
Allow: true,
Access: &rwm,
},
}
} else {
for _, deviceMapping := range c.HostConfig.Devices {
d, err := getDevicesFromPath(deviceMapping)
d, dPermissions, err := getDevicesFromPath(deviceMapping)
if err != nil {
return err
}
devs = append(devs, d...)
devPermissions = append(devPermissions, dPermissions...)
}
}
s.Linux.Devices = append(s.Linux.Devices, devs...)
s.Linux.Resources.Devices = devPermissions
return nil
}

View File

@ -13,6 +13,7 @@ import (
"strconv"
"strings"
"sync"
"syscall"
"time"
"github.com/docker/docker/pkg/homedir"
@ -980,3 +981,29 @@ func (s *DockerSuite) TestRunPidsLimit(c *check.C) {
out = inspectField(c, "skittles", "HostConfig.PidsLimit")
c.Assert(out, checker.Equals, "2", check.Commentf("setting the pids limit failed"))
}
func (s *DockerSuite) TestRunPrivilegedAllowedDevices(c *check.C) {
testRequires(c, DaemonIsLinux)
file := "/sys/fs/cgroup/devices/devices.list"
out, _ := dockerCmd(c, "run", "--privileged", "busybox", "cat", file)
c.Logf("out: %q", out)
c.Assert(strings.TrimSpace(out), checker.Equals, "a *:* rwm")
}
func (s *DockerSuite) TestRunUserDeviceAllowed(c *check.C) {
testRequires(c, DaemonIsLinux)
fi, err := os.Stat("/dev/snd/timer")
if err != nil {
c.Skip("Host does not have /dev/snd/timer")
}
stat, ok := fi.Sys().(*syscall.Stat_t)
if !ok {
c.Skip("Could not stat /dev/snd/timer")
}
file := "/sys/fs/cgroup/devices/devices.list"
out, _ := dockerCmd(c, "run", "--device", "/dev/snd/timer:w", "busybox", "cat", file)
c.Assert(out, checker.Contains, fmt.Sprintf("c %d:%d w", stat.Rdev/256, stat.Rdev%256))
}