rootless: raise an error when trying to use cgroups

https://github.com/containers/libpod/issues/1429#issuecomment-424040416

Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
This commit is contained in:
Giuseppe Scrivano
2018-09-26 13:24:20 +02:00
parent 05fe1bdbbc
commit abde1ef0ef
2 changed files with 108 additions and 85 deletions

View File

@ -91,18 +91,23 @@ func getSeccompConfig(config *CreateConfig, configSpec *spec.Spec) (*spec.LinuxS
} }
func (c *CreateConfig) createBlockIO() (*spec.LinuxBlockIO, error) { func (c *CreateConfig) createBlockIO() (*spec.LinuxBlockIO, error) {
var ret *spec.LinuxBlockIO
bio := &spec.LinuxBlockIO{} bio := &spec.LinuxBlockIO{}
if c.Resources.BlkioWeight > 0 {
ret = bio
bio.Weight = &c.Resources.BlkioWeight bio.Weight = &c.Resources.BlkioWeight
}
if len(c.Resources.BlkioWeightDevice) > 0 { if len(c.Resources.BlkioWeightDevice) > 0 {
var lwds []spec.LinuxWeightDevice var lwds []spec.LinuxWeightDevice
ret = bio
for _, i := range c.Resources.BlkioWeightDevice { for _, i := range c.Resources.BlkioWeightDevice {
wd, err := validateweightDevice(i) wd, err := validateweightDevice(i)
if err != nil { if err != nil {
return bio, errors.Wrapf(err, "invalid values for blkio-weight-device") return ret, errors.Wrapf(err, "invalid values for blkio-weight-device")
} }
wdStat, err := getStatFromPath(wd.path) wdStat, err := getStatFromPath(wd.path)
if err != nil { if err != nil {
return bio, errors.Wrapf(err, "error getting stat from path %q", wd.path) return ret, errors.Wrapf(err, "error getting stat from path %q", wd.path)
} }
lwd := spec.LinuxWeightDevice{ lwd := spec.LinuxWeightDevice{
Weight: &wd.weight, Weight: &wd.weight,
@ -114,34 +119,38 @@ func (c *CreateConfig) createBlockIO() (*spec.LinuxBlockIO, error) {
bio.WeightDevice = lwds bio.WeightDevice = lwds
} }
if len(c.Resources.DeviceReadBps) > 0 { if len(c.Resources.DeviceReadBps) > 0 {
ret = bio
readBps, err := makeThrottleArray(c.Resources.DeviceReadBps, bps) readBps, err := makeThrottleArray(c.Resources.DeviceReadBps, bps)
if err != nil { if err != nil {
return bio, err return ret, err
} }
bio.ThrottleReadBpsDevice = readBps bio.ThrottleReadBpsDevice = readBps
} }
if len(c.Resources.DeviceWriteBps) > 0 { if len(c.Resources.DeviceWriteBps) > 0 {
ret = bio
writeBpds, err := makeThrottleArray(c.Resources.DeviceWriteBps, bps) writeBpds, err := makeThrottleArray(c.Resources.DeviceWriteBps, bps)
if err != nil { if err != nil {
return bio, err return ret, err
} }
bio.ThrottleWriteBpsDevice = writeBpds bio.ThrottleWriteBpsDevice = writeBpds
} }
if len(c.Resources.DeviceReadIOps) > 0 { if len(c.Resources.DeviceReadIOps) > 0 {
ret = bio
readIOps, err := makeThrottleArray(c.Resources.DeviceReadIOps, iops) readIOps, err := makeThrottleArray(c.Resources.DeviceReadIOps, iops)
if err != nil { if err != nil {
return bio, err return ret, err
} }
bio.ThrottleReadIOPSDevice = readIOps bio.ThrottleReadIOPSDevice = readIOps
} }
if len(c.Resources.DeviceWriteIOps) > 0 { if len(c.Resources.DeviceWriteIOps) > 0 {
ret = bio
writeIOps, err := makeThrottleArray(c.Resources.DeviceWriteIOps, iops) writeIOps, err := makeThrottleArray(c.Resources.DeviceWriteIOps, iops)
if err != nil { if err != nil {
return bio, err return ret, err
} }
bio.ThrottleWriteIOPSDevice = writeIOps bio.ThrottleWriteIOPSDevice = writeIOps
} }
return bio, nil return ret, nil
} }
func makeThrottleArray(throttleInput []string, rateType int) ([]spec.LinuxThrottleDevice, error) { func makeThrottleArray(throttleInput []string, rateType int) ([]spec.LinuxThrottleDevice, error) {

View File

@ -159,9 +159,8 @@ func CreateConfigToOCISpec(config *CreateConfig) (*spec.Spec, error) { //nolint
} }
g.AddProcessEnv("container", "podman") g.AddProcessEnv("container", "podman")
canAddResources := !rootless.IsRootless() addedResources := false
if canAddResources {
// RESOURCES - MEMORY // RESOURCES - MEMORY
if config.Resources.Memory != 0 { if config.Resources.Memory != 0 {
g.SetLinuxResourcesMemoryLimit(config.Resources.Memory) g.SetLinuxResourcesMemoryLimit(config.Resources.Memory)
@ -170,18 +169,23 @@ func CreateConfigToOCISpec(config *CreateConfig) (*spec.Spec, error) { //nolint
if config.Resources.MemorySwap == 0 { if config.Resources.MemorySwap == 0 {
g.SetLinuxResourcesMemorySwap(2 * config.Resources.Memory) g.SetLinuxResourcesMemorySwap(2 * config.Resources.Memory)
} }
addedResources = true
} }
if config.Resources.MemoryReservation != 0 { if config.Resources.MemoryReservation != 0 {
g.SetLinuxResourcesMemoryReservation(config.Resources.MemoryReservation) g.SetLinuxResourcesMemoryReservation(config.Resources.MemoryReservation)
addedResources = true
} }
if config.Resources.MemorySwap != 0 { if config.Resources.MemorySwap != 0 {
g.SetLinuxResourcesMemorySwap(config.Resources.MemorySwap) g.SetLinuxResourcesMemorySwap(config.Resources.MemorySwap)
addedResources = true
} }
if config.Resources.KernelMemory != 0 { if config.Resources.KernelMemory != 0 {
g.SetLinuxResourcesMemoryKernel(config.Resources.KernelMemory) g.SetLinuxResourcesMemoryKernel(config.Resources.KernelMemory)
addedResources = true
} }
if config.Resources.MemorySwappiness != -1 { if config.Resources.MemorySwappiness != -1 {
g.SetLinuxResourcesMemorySwappiness(uint64(config.Resources.MemorySwappiness)) g.SetLinuxResourcesMemorySwappiness(uint64(config.Resources.MemorySwappiness))
addedResources = true
} }
g.SetLinuxResourcesMemoryDisableOOMKiller(config.Resources.DisableOomKiller) g.SetLinuxResourcesMemoryDisableOOMKiller(config.Resources.DisableOomKiller)
g.SetProcessOOMScoreAdj(config.Resources.OomScoreAdj) g.SetProcessOOMScoreAdj(config.Resources.OomScoreAdj)
@ -189,28 +193,36 @@ func CreateConfigToOCISpec(config *CreateConfig) (*spec.Spec, error) { //nolint
// RESOURCES - CPU // RESOURCES - CPU
if config.Resources.CPUShares != 0 { if config.Resources.CPUShares != 0 {
g.SetLinuxResourcesCPUShares(config.Resources.CPUShares) g.SetLinuxResourcesCPUShares(config.Resources.CPUShares)
addedResources = true
} }
if config.Resources.CPUQuota != 0 { if config.Resources.CPUQuota != 0 {
g.SetLinuxResourcesCPUQuota(config.Resources.CPUQuota) g.SetLinuxResourcesCPUQuota(config.Resources.CPUQuota)
addedResources = true
} }
if config.Resources.CPUPeriod != 0 { if config.Resources.CPUPeriod != 0 {
g.SetLinuxResourcesCPUPeriod(config.Resources.CPUPeriod) g.SetLinuxResourcesCPUPeriod(config.Resources.CPUPeriod)
addedResources = true
} }
if config.Resources.CPUs != 0 { if config.Resources.CPUs != 0 {
g.SetLinuxResourcesCPUPeriod(cpuPeriod) g.SetLinuxResourcesCPUPeriod(cpuPeriod)
g.SetLinuxResourcesCPUQuota(int64(config.Resources.CPUs * cpuPeriod)) g.SetLinuxResourcesCPUQuota(int64(config.Resources.CPUs * cpuPeriod))
addedResources = true
} }
if config.Resources.CPURtRuntime != 0 { if config.Resources.CPURtRuntime != 0 {
g.SetLinuxResourcesCPURealtimeRuntime(config.Resources.CPURtRuntime) g.SetLinuxResourcesCPURealtimeRuntime(config.Resources.CPURtRuntime)
addedResources = true
} }
if config.Resources.CPURtPeriod != 0 { if config.Resources.CPURtPeriod != 0 {
g.SetLinuxResourcesCPURealtimePeriod(config.Resources.CPURtPeriod) g.SetLinuxResourcesCPURealtimePeriod(config.Resources.CPURtPeriod)
addedResources = true
} }
if config.Resources.CPUsetCPUs != "" { if config.Resources.CPUsetCPUs != "" {
g.SetLinuxResourcesCPUCpus(config.Resources.CPUsetCPUs) g.SetLinuxResourcesCPUCpus(config.Resources.CPUsetCPUs)
addedResources = true
} }
if config.Resources.CPUsetMems != "" { if config.Resources.CPUsetMems != "" {
g.SetLinuxResourcesCPUMems(config.Resources.CPUsetMems) g.SetLinuxResourcesCPUMems(config.Resources.CPUsetMems)
addedResources = true
} }
// Devices // Devices
@ -218,9 +230,11 @@ func CreateConfigToOCISpec(config *CreateConfig) (*spec.Spec, error) { //nolint
// If privileged, we need to add all the host devices to the // If privileged, we need to add all the host devices to the
// spec. We do not add the user provided ones because we are // spec. We do not add the user provided ones because we are
// already adding them all. // already adding them all.
if !rootless.IsRootless() {
if err := config.AddPrivilegedDevices(&g); err != nil { if err := config.AddPrivilegedDevices(&g); err != nil {
return nil, err return nil, err
} }
}
} else { } else {
for _, device := range config.Devices { for _, device := range config.Devices {
if err := addDevice(&g, device); err != nil { if err := addDevice(&g, device); err != nil {
@ -228,7 +242,6 @@ func CreateConfigToOCISpec(config *CreateConfig) (*spec.Spec, error) { //nolint
} }
} }
} }
}
for _, uidmap := range config.IDMappings.UIDMap { for _, uidmap := range config.IDMappings.UIDMap {
g.AddLinuxUIDMapping(uint32(uidmap.HostID), uint32(uidmap.ContainerID), uint32(uidmap.Size)) g.AddLinuxUIDMapping(uint32(uidmap.HostID), uint32(uidmap.ContainerID), uint32(uidmap.Size))
@ -240,13 +253,12 @@ func CreateConfigToOCISpec(config *CreateConfig) (*spec.Spec, error) { //nolint
g.SetProcessNoNewPrivileges(config.NoNewPrivs) g.SetProcessNoNewPrivileges(config.NoNewPrivs)
g.SetProcessApparmorProfile(config.ApparmorProfile) g.SetProcessApparmorProfile(config.ApparmorProfile)
if canAddResources {
blockAccessToKernelFilesystems(config, &g) blockAccessToKernelFilesystems(config, &g)
// RESOURCES - PIDS // RESOURCES - PIDS
if config.Resources.PidsLimit != 0 { if config.Resources.PidsLimit != 0 {
g.SetLinuxResourcesPidsLimit(config.Resources.PidsLimit) g.SetLinuxResourcesPidsLimit(config.Resources.PidsLimit)
} addedResources = true
} }
if config.Systemd && (strings.HasSuffix(config.Command[0], "init") || if config.Systemd && (strings.HasSuffix(config.Command[0], "init") ||
@ -347,7 +359,6 @@ func CreateConfigToOCISpec(config *CreateConfig) (*spec.Spec, error) { //nolint
configSpec.Mounts = supercedeUserMounts(volumeMounts, configSpec.Mounts) configSpec.Mounts = supercedeUserMounts(volumeMounts, configSpec.Mounts)
//--mount //--mount
configSpec.Mounts = supercedeUserMounts(config.initFSMounts(), configSpec.Mounts) configSpec.Mounts = supercedeUserMounts(config.initFSMounts(), configSpec.Mounts)
if canAddResources {
// BLOCK IO // BLOCK IO
blkio, err := config.CreateBlockIO() blkio, err := config.CreateBlockIO()
if err != nil { if err != nil {
@ -355,13 +366,16 @@ func CreateConfigToOCISpec(config *CreateConfig) (*spec.Spec, error) { //nolint
} }
if blkio != nil { if blkio != nil {
configSpec.Linux.Resources.BlockIO = blkio configSpec.Linux.Resources.BlockIO = blkio
} addedResources = true
} }
// If we cannot add resources be sure everything is cleared out if rootless.IsRootless() {
if !canAddResources { if addedResources {
return nil, errors.New("invalid configuration, cannot set resources with rootless containers")
}
configSpec.Linux.Resources = &spec.LinuxResources{} configSpec.Linux.Resources = &spec.LinuxResources{}
} }
return configSpec, nil return configSpec, nil
} }