Skip to content

Commit

Permalink
Merge pull request containers#11212 from flouthoc/check-valid-systemd…
Browse files Browse the repository at this point in the history
…-session

cgroup-manager-systemd: Warn early if user is rootless and no relevent user session is present.
  • Loading branch information
openshift-ci[bot] authored Aug 17, 2021
2 parents d7f0d1f + e7ee15f commit a3d8b48
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 0 deletions.
10 changes: 10 additions & 0 deletions libpod/runtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import (
"github.com/containers/podman/v3/libpod/shutdown"
"github.com/containers/podman/v3/pkg/cgroups"
"github.com/containers/podman/v3/pkg/rootless"
"github.com/containers/podman/v3/pkg/systemd"
"github.com/containers/podman/v3/pkg/util"
"github.com/containers/storage"
"github.com/containers/storage/pkg/unshare"
Expand Down Expand Up @@ -500,6 +501,15 @@ func makeRuntime(ctx context.Context, runtime *Runtime) (retErr error) {
// no containers running. Create immediately a namespace, as
// we will need to access the storage.
if needsUserns {
// warn users if mode is rootless and cgroup manager is systemd
// and no valid systemd session is present
// warn only whenever new namespace is created
if runtime.config.Engine.CgroupManager == config.SystemdCgroupsManager {
unified, _ := cgroups.IsCgroup2UnifiedMode()
if unified && rootless.IsRootless() && !systemd.IsSystemdSessionValid(rootless.GetRootlessUID()) {
logrus.Debug("Invalid systemd user session for current user")
}
}
aliveLock.Unlock() // Unlock to avoid deadlock as BecomeRootInUserNS will reexec.
pausePid, err := util.GetRootlessPauseProcessPidPathGivenDir(runtime.config.Engine.TmpDir)
if err != nil {
Expand Down
98 changes: 98 additions & 0 deletions pkg/systemd/dbus.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,106 @@ import (
"github.com/containers/podman/v3/pkg/rootless"
"github.com/coreos/go-systemd/v22/dbus"
godbus "github.com/godbus/dbus/v5"
"github.com/sirupsen/logrus"
)

// IsSystemdSessionValid checks if sessions is valid for provided rootless uid.
func IsSystemdSessionValid(uid int) bool {
var conn *godbus.Conn
var err error
var object godbus.BusObject
var seat0Path godbus.ObjectPath
dbusDest := "org.freedesktop.login1"
dbusInterface := "org.freedesktop.login1.Manager"
dbusPath := "/org/freedesktop/login1"

if rootless.IsRootless() {
conn, err = GetLogindConnection(rootless.GetRootlessUID())
object = conn.Object(dbusDest, godbus.ObjectPath(dbusPath))
if err != nil {
//unable to fetch systemd object for logind
logrus.Debugf("systemd-logind: %s", err)
return false
}
object = conn.Object(dbusDest, godbus.ObjectPath(dbusPath))
if err := object.Call(dbusInterface+".GetSeat", 0, "seat0").Store(&seat0Path); err != nil {
//unable to get seat0 path.
logrus.Debugf("systemd-logind: %s", err)
return false
}
seat0Obj := conn.Object(dbusDest, seat0Path)
activeSession, err := seat0Obj.GetProperty(dbusDest + ".Seat.ActiveSession")
if err != nil {
//unable to get active sessions.
logrus.Debugf("systemd-logind: %s", err)
return false
}
activeSessionMap, ok := activeSession.Value().([]interface{})
if !ok || len(activeSessionMap) < 2 {
//unable to get active session map.
logrus.Debugf("systemd-logind: %s", err)
return false
}
activeSessionPath, ok := activeSessionMap[1].(godbus.ObjectPath)
if !ok {
//unable to fetch active session path.
logrus.Debugf("systemd-logind: %s", err)
return false
}
activeSessionObj := conn.Object(dbusDest, activeSessionPath)
sessionUser, err := activeSessionObj.GetProperty(dbusDest + ".Session.User")
if err != nil {
//unable to fetch session user from activeSession path.
logrus.Debugf("systemd-logind: %s", err)
return false
}
dbusUser, ok := sessionUser.Value().([]interface{})
if !ok {
// not a valid user.
return false
}
if len(dbusUser) < 2 {
// not a valid session user.
return false
}
activeUID, ok := dbusUser[0].(uint32)
if !ok {
return false
}
//active session found which belongs to following rootless user
if activeUID == uint32(uid) {
return true
}
return false
}
return true
}

// GetDbusConnection returns an user connection to D-BUS
func GetLogindConnection(uid int) (*godbus.Conn, error) {
return dbusAuthConnectionLogind(uid)
}

func dbusAuthConnectionLogind(uid int) (*godbus.Conn, error) {
var conn *godbus.Conn
var err error
conn, err = godbus.SystemBusPrivate()
if err != nil {
return nil, err
}
methods := []godbus.Auth{godbus.AuthExternal(strconv.Itoa(uid))}
if err = conn.Auth(methods); err != nil {
conn.Close()
return nil, err
}
err = conn.Hello()
if err != nil {
conn.Close()
return nil, err
}
return conn, nil
}

func dbusAuthRootlessConnection(createBus func(opts ...godbus.ConnOption) (*godbus.Conn, error)) (*godbus.Conn, error) {
conn, err := createBus()
if err != nil {
Expand Down

0 comments on commit a3d8b48

Please sign in to comment.