From a95483402ef53ec0b82d85b9fb32c559c19b0450 Mon Sep 17 00:00:00 2001 From: Aleksa Sarai Date: Thu, 17 Dec 2015 20:13:06 +1100 Subject: [PATCH] libcontainer: cgroups: loudly fail with Set It is vital to loudly fail when a user attempts to set a cgroup limit (rather than using the system default). Otherwise the user will assume they have security they do not actually have. This mirrors the original Apply() (that would set cgroup configs) semantics. Signed-off-by: Aleksa Sarai --- libcontainer/cgroups/fs/apply_raw.go | 18 +++++++++++++----- libcontainer/cgroups/systemd/apply_systemd.go | 13 ++++++++----- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/libcontainer/cgroups/fs/apply_raw.go b/libcontainer/cgroups/fs/apply_raw.go index c67c55acd..8eb71b4dd 100644 --- a/libcontainer/cgroups/fs/apply_raw.go +++ b/libcontainer/cgroups/fs/apply_raw.go @@ -171,16 +171,24 @@ func (m *Manager) GetStats() (*cgroups.Stats, error) { } func (m *Manager) Set(container *configs.Config) error { - for name, path := range m.Paths { + for _, sys := range subsystems { // We can't set this here, because after being applied, memcg doesn't // allow a non-empty cgroup from having its limits changed. - if name == "memory" { + if sys.Name() == "memory" { continue } - sys, err := subsystems.Get(name) - if err == errSubsystemDoesNotExist || !cgroups.PathExists(path) { - continue + + // Generate fake cgroup data. + d, err := getCgroupData(container.Cgroups, -1) + if err != nil { + return err } + // Get the path, but don't error out if the cgroup wasn't found. + path, err := d.path(sys.Name()) + if err != nil && !cgroups.IsNotFound(err) { + return err + } + if err := sys.Set(path, container.Cgroups); err != nil { return err } diff --git a/libcontainer/cgroups/systemd/apply_systemd.go b/libcontainer/cgroups/systemd/apply_systemd.go index 952820e62..b943e9dae 100644 --- a/libcontainer/cgroups/systemd/apply_systemd.go +++ b/libcontainer/cgroups/systemd/apply_systemd.go @@ -431,16 +431,19 @@ func (m *Manager) GetStats() (*cgroups.Stats, error) { } func (m *Manager) Set(container *configs.Config) error { - for name, path := range m.Paths { + for _, sys := range subsystems { // We can't set this here, because after being applied, memcg doesn't // allow a non-empty cgroup from having its limits changed. - if name == "memory" { + if sys.Name() == "memory" { continue } - sys, err := subsystems.Get(name) - if err == errSubsystemDoesNotExist || !cgroups.PathExists(path) { - continue + + // Get the subsystem path, but don't error out for not found cgroups. + path, err := getSubsystemPath(container.Cgroups, sys.Name()) + if err != nil && !cgroups.IsNotFound(err) { + return err } + if err := sys.Set(path, container.Cgroups); err != nil { return err }