diff options
author | Giuseppe Scrivano <gscrivan@redhat.com> | 2019-09-06 15:30:30 +0200 |
---|---|---|
committer | Giuseppe Scrivano <gscrivan@redhat.com> | 2019-09-12 08:35:26 +0200 |
commit | afd0818326aa37f03a3bc74f0269a06a403db16d (patch) | |
tree | 8ebc91774297027f2c244b22a4428222d42fa3ad /pkg/cgroups/cgroups_supported.go | |
parent | b94a5e241095a55a6838970148d296e109b2afd1 (diff) | |
download | podman-afd0818326aa37f03a3bc74f0269a06a403db16d.tar.gz podman-afd0818326aa37f03a3bc74f0269a06a403db16d.tar.bz2 podman-afd0818326aa37f03a3bc74f0269a06a403db16d.zip |
rootless: automatically create a systemd scope
when running in rootless mode and using systemd as cgroup manager
create automatically a systemd scope when the user doesn't own the
current cgroup.
This solves a couple of issues:
on cgroup v2 it is necessary that a process before it can moved to a
different cgroup tree must be in a directory owned by the unprivileged
user. This is not always true, e.g. when creating a session with su
-l.
Closes: https://github.com/containers/libpod/issues/3937
Also, for running systemd in a container it was before necessary to
specify "systemd-run --scope --user podman ...", now this is done
automatically as part of this PR.
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
Diffstat (limited to 'pkg/cgroups/cgroups_supported.go')
-rw-r--r-- | pkg/cgroups/cgroups_supported.go | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/pkg/cgroups/cgroups_supported.go b/pkg/cgroups/cgroups_supported.go index fcd44dfc8..2a36777d4 100644 --- a/pkg/cgroups/cgroups_supported.go +++ b/pkg/cgroups/cgroups_supported.go @@ -3,8 +3,15 @@ package cgroups import ( + "bufio" + "fmt" + "os" + "path/filepath" + "strings" "sync" "syscall" + + "github.com/pkg/errors" ) var ( @@ -25,3 +32,58 @@ func IsCgroup2UnifiedMode() (bool, error) { }) return isUnified, isUnifiedErr } + +// UserOwnsCurrentSystemdCgroup checks whether the current EUID owns the +// current cgroup. +func UserOwnsCurrentSystemdCgroup() (bool, error) { + uid := os.Geteuid() + + cgroup2, err := IsCgroup2UnifiedMode() + if err != nil { + return false, err + } + + f, err := os.Open("/proc/self/cgroup") + if err != nil { + return false, errors.Wrapf(err, "open file /proc/self/cgroup") + } + defer f.Close() + + scanner := bufio.NewScanner(f) + for scanner.Scan() { + line := scanner.Text() + parts := strings.SplitN(line, ":", 3) + + if len(parts) < 3 { + continue + } + + var cgroupPath string + + if cgroup2 { + cgroupPath = filepath.Join(cgroupRoot, parts[2]) + } else { + if parts[1] != "name=systemd" { + continue + } + cgroupPath = filepath.Join(cgroupRoot, "systemd", parts[2]) + } + + st, err := os.Stat(cgroupPath) + if err != nil { + return false, err + } + s := st.Sys() + if s == nil { + return false, fmt.Errorf("error stat cgroup path %s", cgroupPath) + } + + if int(s.(*syscall.Stat_t).Uid) != uid { + return false, nil + } + } + if err := scanner.Err(); err != nil { + return false, errors.Wrapf(err, "parsing file /proc/self/cgroup") + } + return true, nil +} |