From: Alan Jenkins Date: Thu, 22 Feb 2018 20:38:44 +0000 (+0000) Subject: login: fix user@.service case, so we don't allow nested sessions (#8051) X-Git-Tag: v238~64 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e8a3144ec4ff332bd63644e468a98e1a7e06e7e4;p=thirdparty%2Fsystemd.git login: fix user@.service case, so we don't allow nested sessions (#8051) > logind sessions are mostly bound to the audit session concept, and audit > sessions remain unaffected by "su", in fact they are defined to be > "sealed off", i.e. in a way that if a process entered a session once, it > will always stay with it, and so will its children, i.e. the only way to > get a new session is by forking off something off PID 1 (or something > similar) that never has been part of a session. The code had a gap. user@.service is a special case PAM session which does not create a logind session. Let's remember to check for it. Fixes #8021 --- diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c index a8c1b71e7e7..07cb2571518 100644 --- a/src/login/logind-dbus.c +++ b/src/login/logind-dbus.c @@ -41,6 +41,7 @@ #include "mkdir.h" #include "path-util.h" #include "process-util.h" +#include "cgroup-util.h" #include "selinux-util.h" #include "sleep-config.h" #include "special.h" @@ -658,6 +659,7 @@ static int method_list_inhibitors(sd_bus_message *message, void *userdata, sd_bu static int method_create_session(sd_bus_message *message, void *userdata, sd_bus_error *error) { const char *service, *type, *class, *cseat, *tty, *display, *remote_user, *remote_host, *desktop; uint32_t audit_id = 0; + _cleanup_free_ char *unit = NULL; _cleanup_free_ char *id = NULL; Session *session = NULL; Manager *m = userdata; @@ -787,8 +789,15 @@ static int method_create_session(sd_bus_message *message, void *userdata, sd_bus return r; } - r = manager_get_session_by_pid(m, leader, NULL); - if (r > 0) + /* + * Check if we are already in a logind session. Or if we are in user@.service + * which is a special PAM session that avoids creating a logind session. + */ + r = cg_pid_get_unit(leader, &unit); + if (r < 0) + return r; + if (hashmap_get(m->session_units, unit) || + hashmap_get(m->user_units, unit)) return sd_bus_error_setf(error, BUS_ERROR_SESSION_BUSY, "Already running in a session"); /*