mirror of
https://github.com/containers/podman.git
synced 2025-06-23 02:18:13 +08:00
Merge pull request #11212 from flouthoc/check-valid-systemd-session
cgroup-manager-systemd: Warn early if user is rootless and no relevent user session is present.
This commit is contained in:
@ -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"
|
||||
@ -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 {
|
||||
|
@ -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 {
|
||||
|
Reference in New Issue
Block a user