aboutsummaryrefslogtreecommitdiff
path: root/pkg/cgroups/cgroups_supported.go
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/cgroups/cgroups_supported.go')
-rw-r--r--pkg/cgroups/cgroups_supported.go62
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
+}