From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Thu, 3 Mar 2022 14:55:53 +0100 Subject: [PATCH] Implement common function to create DeviceCgroup rules Signed-off-by: Stefan Agner --- libcontainer/specconv/spec_linux.go | 84 +++++++++++++++++------------ 1 file changed, 49 insertions(+), 35 deletions(-) diff --git a/libcontainer/specconv/spec_linux.go b/libcontainer/specconv/spec_linux.go index 37507b41..5aafa2ef 100644 --- a/libcontainer/specconv/spec_linux.go +++ b/libcontainer/specconv/spec_linux.go @@ -787,6 +787,48 @@ func initSystemdProps(spec *specs.Spec) ([]systemdDbus.Property, error) { return sp, nil } +func CreateCgroupDeviceConfig(r *configs.Resources, specr *specs.LinuxResources, defaultDevs []*devices.Device) error { + if specr != nil { + for i, d := range specr.Devices { + var ( + t = "a" + major = int64(-1) + minor = int64(-1) + ) + if d.Type != "" { + t = d.Type + } + if d.Major != nil { + major = *d.Major + } + if d.Minor != nil { + minor = *d.Minor + } + if d.Access == "" { + return fmt.Errorf("device access at %d field cannot be empty", i) + } + dt, err := stringToCgroupDeviceRune(t) + if err != nil { + return err + } + r.Devices = append(r.Devices, &devices.Rule{ + Type: dt, + Major: major, + Minor: minor, + Permissions: devices.Permissions(d.Access), + Allow: d.Allow, + }) + } + } + + // Append the default allowed devices to the end of the list. + for _, device := range defaultDevs { + r.Devices = append(r.Devices, &device.Rule) + } + + return nil +} + func CreateCgroupConfig(opts *CreateOpts, defaultDevs []*devices.Device) (*cgroups.Cgroup, error) { var ( myCgroupPath string @@ -843,39 +885,10 @@ func CreateCgroupConfig(opts *CreateOpts, defaultDevs []*devices.Device) (*cgrou // In rootless containers, any attempt to make cgroup changes is likely to fail. // libcontainer will validate this but ignores the error. + var r *specs.LinuxResources if spec.Linux != nil { - r := spec.Linux.Resources + r = spec.Linux.Resources if r != nil { - for i, d := range r.Devices { - var ( - t = "a" - major = int64(-1) - minor = int64(-1) - ) - if d.Type != "" { - t = d.Type - } - if d.Major != nil { - major = *d.Major - } - if d.Minor != nil { - minor = *d.Minor - } - if d.Access == "" { - return nil, fmt.Errorf("device access at %d field cannot be empty", i) - } - dt, err := stringToCgroupDeviceRune(t) - if err != nil { - return nil, err - } - c.Resources.Devices = append(c.Resources.Devices, &devices.Rule{ - Type: dt, - Major: major, - Minor: minor, - Permissions: devices.Permissions(d.Access), - Allow: d.Allow, - }) - } if r.Memory != nil { if r.Memory.Limit != nil { c.Resources.Memory = *r.Memory.Limit @@ -997,12 +1010,13 @@ func CreateCgroupConfig(opts *CreateOpts, defaultDevs []*devices.Device) (*cgrou c.Resources.Unified = maps.Clone(r.Unified) } } - } - // Append the default allowed devices to the end of the list. - for _, device := range defaultDevs { - c.Resources.Devices = append(c.Resources.Devices, &device.Rule) + err := CreateCgroupDeviceConfig(c.Resources, r, defaultDevs) + if err != nil { + return nil, err + } } + return c, nil }